2016-05-22 88 views
2

我有一系列的文件名,提取特定元素中的R

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") 

我想提取的第二和第三塊「 - 」在每個文件名,然後列出這兩個區塊作爲矩陣中的兩列。我用下面的代碼進行:

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 

這是正確的。但是我想知道是否有更方便的方法來解決這個問題,比如「gsub」?謝謝。

+2

查看'?regexpr'幫助文件底部的'parse_one'示例顯示瞭如何使用perl樣式正則表達式 – Shape

回答

1

我們可以使用subread.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 
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" 
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 

然後你就可以切下來到你想要的兩列。