1

我有一个具有以下模式的子字符串列表:

my.list <- list("file1\\subfile1-D.ext", "file12\\subfile9-D.ext", "file2\\subfile113-D.ext")

等等。我想将文件编号和子文件编号提取到包含文件/子文件编号的数字数据框中。到目前为止,我一直在使用以下方法:

extract.file <- function(file.name){
  file.name <- sub("file", "", file.name)
  file.name <- sub("\\\\*subfile.*", "", file.name)
}

extract.subfile <- function(subfile.name){
  subfile.name <- sub("file.*subfile", "", subfile.name)
  subfile.name <- sub("-D.ext", "", subfile.name)
}

name.file <- lapply(my.list, extract.file)
name.file <- as.numeric(unlist(name.file))
name.subfile <- lapply(my.list, extract.subfile)
name.subfile <- as.numeric(unlist(name.subfile))

my.df <- data.frame(file=name.file, subfile=name.subfile)

我还尝试过首先使用substring.locationfrom stringrlibrary 提取字符串位置(这会产生另一个具有开始和结束值的列表),然后遍历这两个列表,但这又变得太复杂了。有没有更好的方法来实现目标?

4

2 回答 2

5

一些替代方案:
[编辑:strsplit 可以接受一个数组并返回一个列表,与在 rbind 调用中嵌套应用相比,将时间缩短了大约一半。]

my.df <- do.call( rbind, strsplit( unlist(my.list), split="(\\\\|-D.ext)" ) )
my.df <- data.frame( my.df )
names( my.df ) <- c("file", "subfile")

或者

my.df <- do.call( rbind, strsplit( unlist(my.list), split="[^[:alnum:]]" ) )[, 1:2]
my.df <- data.frame( my.df )
names( my.df ) <- c("file", "subfile")

以这种方式做事的一件事是,如果所有输入都遵循原始my.list样本,那么您将留下非常毫无价值和冗余的数据。

也许更好的解决方案可能是;

# Not sure why strsplit() returns an empty string on the first non-digit match,
# but it does and we account for it by dropping the first returned column.
my.list <- unlist( my.list )
my.df <- do.call( rbind, strsplit( my.list, split="[^[:digit:]]+" ) )[,-1]
my.df <- data.frame( my.list, my.df )
names( my.df ) <- c( "orig", "file", "subfile" )

我们已经节省了相当多的内存/存储,而没有所有这些重复,并且我们获得了操作事物的能力,而无需对文本/字符排序/表示大惊小怪。


检查?strsplit,?regex?grep匹配的东西。

data.frame 设置非常简单...... strsplit 接受一个向量并返回一个列表,而 do.call 需要一个列表来绑定在一起。

于 2012-08-13T17:28:01.277 回答
2

这是一个带有反向引用的正则表达式,似乎可以满足您的要求:

sapply(my.list, function(x)gsub(".*\\\\(.*)-D\\.ext", "\\1", x))
[1] "subfile1"   "subfile9"   "subfile113"

"\\1"是一个反向引用,它返回括号内字符串的值。

于 2012-08-13T14:59:22.320 回答