我有一系列文件名,
a<-c("asd1-36457-1-qwe-20.txt","asd-3234-4-qwe-20.txt","asd1-5457-3-qwe-20.txt",
"asd1-546-2-qwe-20.txt","asd1-789-1-qwe-20.txt","asd-542112-7-qwe-20.txt",
"asd-754-4-qwe-20.txt","asd-3466-3-qwe-20.txt","asd-4675-2-qwe-20.txt")
我想提取&#34; - &#34;之间的第二和第三块。在每个文件名中,然后将这两个块列为矩阵中的两列。我使用以下代码继续:
b<-as.numeric(unlist(Map(function(x) x[2], strsplit(a,"-"))))
c<-as.numeric(unlist(Map(function(x) x[3], strsplit(a,"-"))))
cbind(b,c)
结果如下:
b c
[1,] 36457 1
[2,] 3234 4
[3,] 5457 3
[4,] 546 2
[5,] 789 1
[6,] 542112 7
[7,] 754 4
[8,] 3466 3
[9,] 4675 2
是对的。但是我想知道是否有更方便的方法,例如&#34; gsub&#34;来解决这个问题?感谢。
答案 0 :(得分:1)
我们可以将sub
与read.csv
一起使用。我们在字符串(-
)的开头(^
)之后再添加一个不是[^-]+
的字符,后跟一个-
后跟数字\\d+
}}我们放置在一个捕获组((...)
)后跟一个-
和另一个捕获组,以获取数字后跟一个或多个字符(.*
)。将其替换为由,
分隔的捕获组的反向引用。这可用于read.csv
阅读。
read.csv(text=sub("^[^-]+-(\\d+)-(\\d+).*", "\\1,\\2", a),
header=FALSE, col.names = c('b', 'c'))
# b c
#1 36457 1
#2 3234 4
#3 5457 3
#4 546 2
#5 789 1
#6 542112 7
#7 754 4
#8 3466 3
#9 4675 2
或另一个选项是fread
我们可以select
感兴趣的列
library(data.table)
fread(paste(a, collapse="\n"), sep="-", select = 2:3, col.names = c('b', 'c'))
# b c
#1: 36457 1
#2: 3234 4
#3: 5457 3
#4: 546 2
#5: 789 1
#6: 542112 7
#7: 754 4
#8: 3466 3
#9: 4675 2
答案 1 :(得分:0)
与您的方法相似但更短的方法是:
do.call(rbind, lapply(strsplit(a, "-"), `[`, c(2,3)))
[,1] [,2]
[1,] "36457" "1"
[2,] "3234" "4"
[3,] "5457" "3"
[4,] "546" "2"
[5,] "789" "1"
[6,] "542112" "7"
[7,] "754" "4"
[8,] "3466" "3"
[9,] "4675" "2"
答案 2 :(得分:0)
akrun答案的后续跟进:
> read.table(text=a, sep='-', col.names=letters[1:5])
a b c d e
1 asd1 36457 1 qwe 20.txt
2 asd 3234 4 qwe 20.txt
3 asd1 5457 3 qwe 20.txt
4 asd1 546 2 qwe 20.txt
5 asd1 789 1 qwe 20.txt
6 asd 542112 7 qwe 20.txt
7 asd 754 4 qwe 20.txt
8 asd 3466 3 qwe 20.txt
9 asd 4675 2 qwe 20.txt
然后你可以将它分割成你想要的两列。