我试图使用R提取文件名的一部分,我对如何从这里解决这个问题有一个模糊的想法:extract part of a file name in R 但是,我无法在我的文件名列表中使用它
文件名示例:
"Species Count (2011-12-15-07-09-39).xls"
"Species Count 0511.xls"
"Species Count 151112.xls"
"Species Count1011.xls"
"Species Count2012-01.xls"
"Species Count201207.xls"
"Species Count2013-01-15.xls"
某些文件名在Species Count和日期之间有一个空格,有些没有空格,它们的长度不同,有些包含括号。我只想提取文件名的数字部分并保留 - ' s。因此,例如对于上面的数据我会:
预期输出:
2011-12-15-07-09-39 , 0511 , 151112 , 1011 , 2012-01 , 201207 , 2013-01-15
答案 0 :(得分:5)
这是一种方式:
regmatches(tt, regexpr("[0-9].*[0-9]", tt))
我认为你的文件名中没有其他数字。因此,我们只搜索数字的开头并使用贪婪的运算符.*
,以便捕获最后一个数字之前的所有内容。这是使用regexpr
完成的,它将获得匹配的位置。然后我们使用regmatches
从这些匹配的位置中提取(子)字符串。
其中tt
是:
tt <- c("Species Count (2011-12-15-07-09-39).xls", "Species Count 0511.xls",
"Species Count 151112.xls", "Species Count1011.xls",
"Species Count2012-01.xls", "Species Count201207.xls",
"Species Count2013-01-15.xls")
那里有一些不错的答案。所以,是时候进行基准测试了:)
tt <- rep(tt, 1e5) # tt is from above
require(microbenchmark)
require(stringr)
aa <- function() regmatches(tt, regexpr("[0-9].*[0-9]", tt))
bb <- function() gsub("[A-z \\.\\(\\)]", "", tt)
cc <- function() str_extract(tt,'([0-9]|[0-9][-])+')
microbenchmark(arun <- aa(), agstudy <- cc(), Jean <- bb(), times=25)
Unit: seconds
expr min lq median uq max neval
arun <- aa() 1.951362 2.064055 2.198644 2.397724 3.236296 25
agstudy <- cc() 2.489993 2.685285 2.991796 3.198133 3.762166 25
Jean <- bb() 7.824638 8.026595 9.145490 9.788539 10.926665 25
identical(arun, agstudy) # TRUE
identical(arun, Jean) # TRUE
答案 1 :(得分:4)
使用函数gsub()
删除所有字母,空格,句点和括号。然后你将留下数字和连字符。例如,
x <- c("Species Count (2011-12-15-07-09-39).xls", "Species Count 0511.xls",
"Species Count 151112.xls", "Species Count1011.xls", "Species Count2012-01.xls",
"Species Count201207.xls", "Species Count2013-01-15.xls")
gsub("[A-z \\.\\(\\)]", "", x)
[1] "2011-12-15-07-09-39" "0511" "151112"
[4] "1011" "2012-01" "201207"
[7] "2013-01-15"
答案 2 :(得分:2)
如果您担心速度问题,可以使用sub
反向引用来提取所需的部分。另请注意,perl=TRUE
通常更快(根据?grep
)。
jj <- function() sub("[^0-9]*([0-9].*[0-9])[^0-9]*", "\\1", tt, perl=TRUE)
aa <- function() regmatches(tt, regexpr("[0-9].*[0-9]", tt, perl=TRUE))
# Run on R-2.15.2 on 32-bit Windows
microbenchmark(arun <- aa(), josh <- jj(), times=25)
# Unit: milliseconds
# expr min lq median uq max
# 1 arun <- aa() 2156.5024 2189.5168 2191.9972 2195.4176 2410.3255
# 2 josh <- jj() 390.0142 390.8956 391.6431 394.5439 493.2545
identical(arun, josh) # TRUE
# Run on R-3.0.1 on 64-bit Ubuntu
microbenchmark(arun <- aa(), josh <- jj(), times=25)
# Unit: seconds
# expr min lq median uq max neval
# arun <- aa() 1.794522 1.839044 1.858556 1.894946 2.207016 25
# josh <- jj() 1.003365 1.008424 1.009742 1.059129 1.074057 25
identical(arun, josh) # still TRUE
答案 3 :(得分:1)
使用stringr
包提取所有仅包含数字或数字的字符串,后跟-
:
library(stringr)
str_extract(ll,'([0-9]|[0-9][-])+')
[1] "2011-12-15-07-09-39" "0511"
"151112" "1011" "2012-01"
[6] "201207" "2013-01-15"