2016-05-22 2 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

Мы можем использовать 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 
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 

Затем вы можете разрезать это вниз только для двух столбцов, которые вы хотите.

Смежные вопросы