2016-04-28 4 views
0
library(plyr) 
library(stringr) 



###example data 
examp<- data.frame(id_info = c("123", "3464", "7156", "3171", "5299", "4541", "4956", "9926", "8418", "1392", "9080", "6455", "2423", "9101", "7807", "5195", "7827", "365", "9062", "5558", "239", "8700", "6995", "9853"), 
        filterme1 = c("ABB123460sadjasd", "ABB123461asjdjs", "ABB123462ranogvmg", "ABB123463dkfohsd", "ABB123464fff///sss", "ABB123465jfsdf", "ABB123466 sdf", "ABB123467 sdf", "ABB123468 fff///sss", "ABB123469 ty", "ABB123470 fff///sss", "ABB123471 dfs", "ABB123472 ", "ABB123473 gt", "ABB123474 y", "ABB123475 f", "ABB123476 gfgABB123462", "ABB123477 dsd", "ABB123478 re", "ABB123479 fgh", "ABB123480 tu", "ABB123481 yu", "ABB123482 dfg", "ABB123483 s"), 
        filterme2 = c("sadjasdABB123460", "asjdjsABB123461", "ranogvmgABB123462", "dkfohsdABB123463", "fff///sssABB123464", "jfsdfABB123465", "sdfABB123466", "sdfABB123467", "fff///sssABB123468", "tyABB123469", "fff///sssABB123470", "dfsABB123471", "ABB123472", "gtABB123473", "yABB123474", "fABB123475", "ABB123462gfgABB123476", "dsdABB123477", "reABB123478", "fghABB123479", "tuABB123480", "yuABB123481", "dfgABB123482", "sABB123483")) 

##id_info should be factor even tho it is numeric 
str(examp) 

Я хочу извлечь элемент из строк. Элемент должен начинаться с «ABB» и следовать за ним, а затем 6 цифр.R string_extract_all зацикливается через фрейм данных с помощью plyr

#extract out all strings that begin with ABB and are followed by 7 digits 
examp_str<-str_extract_all(as.character(examp$filterme1),pattern="ABB[0-9]{6}") 
length(examp_str) 
#thanks for the help with the expression 

Ниже представлена ​​моя попытка использовать мою функцию stringr во всей области данных.

#Is this how I can eventually loop though the whole dataframe? I know I will create a list, but this isn't quite right. 
examp_str_big<-dlply(.data=examp, 1, 
        function(x) str_extract_all(x,pattern="ABB[0-9]{6}")) 

После того, как создать список, я хочу попробовать и поставить все обратно в данных frame.I нашли link here о вводе неизвестных длин списков в dataframes, но я не уверен, если я мог бы использовать это или нет.

indx <- sapply(examp_str_big, length) 
#indx <- lengths(lst) 
res <- as.data.frame(do.call(rbind,lapply(examp_str_big, `length<-`, 
              max(indx)))) 

colnames(res) <- names(examp_str_big[[which.max(indx)]]) 
str(res) 

Так что мой желаемый конечный результат будет выглядеть следующим образом:

id_info filterme1 filterme2 filterme3 filterme4 
123  ABB123460    ABB123460 
3464 ABB123461    ABB123461 
7156 ABB123462    ABB123462 
3171 ABB123463    ABB123463 
5299 ABB123464    ABB123464 
4541 ABB123465    ABB123465 
4956 ABB123466    ABB123466 
9926 ABB123467    ABB123467 
8418 ABB123468    ABB123468 
1392 ABB123469    ABB123469 
9080 ABB123470    ABB123470 
6455 ABB123471    ABB123471 
2423 ABB123472    ABB123472 
9101 ABB123473    ABB123473 
7807 ABB123474    ABB123474 
5195 ABB123475    ABB123475 
7827 ABB123476 ABB123462 ABB123462 ABB1234576 
365  ABB123477    ABB123477 
9062 ABB123478    ABB123478 
5558 ABB123479    ABB123479 
239  ABB123480    ABB123480 
8700 ABB123481    ABB123481 
6995 ABB123482    ABB123482 
9853 ABB123483    ABB123483 

Моя текущая datset длиннее и имеет более "filterme" столбцы. Любая помощь будет принята с благодарностью. Если есть еще один более умный способ достичь этой цели, я бы с удовольствием это услышал.

Спасибо.

+0

Эта модель будет соответствовать этому ABB следует 7 цифр, как вы упомянули: ' 'ABB [0-9] {7}'' – Gopala

+0

Да что выражение делает работу, Спасибо. У вас есть идеи для второй части вопроса? –

+0

Возможно, вы захотите посмотреть 'disest' из пакета' tidyr'. Он обеспечивает результат в длинном формате. – Gopala

ответ

1

Вот один подход (основанный на исходном кадре данных examp, который я предполагаю, читается с stringsAsFactors = FALSE):

library(stringr) 
# Extract all occurrences of patterns (NOTE: I am using 6 digits 
# since no 7 digits example in provided sample data. Modify to 7. 
examp$pattern <- str_extract_all(examp$filterme1, 'ABB[0-9]{6}') 

# Append columns for each found pattern 
maxlength <- max(sapply(examp$pattern, length)) 
examp <- cbind(examp, 
       as.data.frame(do.call(rbind, 
            lapply(examp$pattern, 
              function(x) { 
               s <- strsplit(x, ' ') 
               c(s, rep(NA, maxlength - length(s))) 
               })))) 

# This will result in a wider data frame with all found patterns appended 
# as new columns 

examp 

    id_info    filterme1    filterme2    pattern  V1 
1  123  ABB123460sadjasd  sadjasdABB123460   ABB123460 ABB123460 
2  3464  ABB123461asjdjs  asjdjsABB123461   ABB123461 ABB123461 
3  7156  ABB123462ranogvmg  ranogvmgABB123462   ABB123462 ABB123462 
4  3171  ABB123463dkfohsd  dkfohsdABB123463   ABB123463 ABB123463 
5  5299  ABB123464fff///sss fff///sssABB123464   ABB123464 ABB123464 
6  4541   ABB123465jfsdf  jfsdfABB123465   ABB123465 ABB123465 
7  4956   ABB123466 sdf   sdfABB123466   ABB123466 ABB123466 
8  9926   ABB123467 sdf   sdfABB123467   ABB123467 ABB123467 
9  8418 ABB123468 fff///sss fff///sssABB123468   ABB123468 ABB123468 
10 1392   ABB123469 ty   tyABB123469   ABB123469 ABB123469 
11 9080 ABB123470 fff///sss fff///sssABB123470   ABB123470 ABB123470 
12 6455   ABB123471 dfs   dfsABB123471   ABB123471 ABB123471 
13 2423    ABB123472    ABB123472   ABB123472 ABB123472 
14 9101   ABB123473 gt   gtABB123473   ABB123473 ABB123473 
15 7807   ABB123474 y   yABB123474   ABB123474 ABB123474 
16 5195   ABB123475 f   fABB123475   ABB123475 ABB123475 
17 7827 ABB123476 gfgABB123462 ABB123462gfgABB123476 ABB123476, ABB123462 ABB123476 
18  365   ABB123477 dsd   dsdABB123477   ABB123477 ABB123477 
19 9062   ABB123478 re   reABB123478   ABB123478 ABB123478 
20 5558   ABB123479 fgh   fghABB123479   ABB123479 ABB123479 
21  239   ABB123480 tu   tuABB123480   ABB123480 ABB123480 
22 8700   ABB123481 yu   yuABB123481   ABB123481 ABB123481 
23 6995   ABB123482 dfg   dfgABB123482   ABB123482 ABB123482 
24 9853   ABB123483 s   sABB123483   ABB123483 ABB123483 
      V2 
1   NA 
2   NA 
3   NA 
4   NA 
5   NA 
6   NA 
7   NA 
8   NA 
9   NA 
10  NA 
11  NA 
12  NA 
13  NA 
14  NA 
15  NA 
16  NA 
17 ABB123462 
18  NA 
19  NA 
20  NA 
21  NA 
22  NA 
23  NA 
24  NA 

В этом случае, только две новые столбцы добавляются, так как есть максимум два вхождения образцов (даже модифицированных до 6 выше) в предоставленные данные выборки.

EDIT: Добавление кода, который соответствует шаблону по нескольким столбцам (в данном случае filterme1 и filterme2):

library(tidyr) 
examp <- unite(examp, filterme, filterme1, filterme2, remove = FALSE) 
examp$pattern <- str_extract_all(examp$filterme, 'ABB[0-9]{6}') 

На данный момент, вы можете запустить остальную часть кода выше после строки, где examp$pattern назначена ,

+0

Благодарим вас за быстрый ответ. Когда я запускаю этот код, я получаю сообщение об ошибке: «Ошибка в FUN (X [[i]], ...): объект« maxlength »не найден» –

+0

Так извините ... одна из строк кода, которую я написал, отсутствует. Ред. – Gopala

+0

Это отлично работает, если я хочу, чтобы функция была применена только к первому столбцу моих данных. Я не вижу, что он может применить str_extract_all во втором столбце или (n) столбцах в фрейме данных. –

0

Мы можем также использовать функцию lengths

lst <- str_extract_all(examp$filterme1, 'ABB[0-9]{6}') 
m1 <- do.call(rbind, lapply(lst, `length<-`, max(lengths(lst)))) 
examp[paste0("pattern", seq_len(ncol(m1)))] <- m1 
examp 
# id_info    filterme1    filterme2 pattern1 pattern2 
#1  123  ABB123460sadjasd  sadjasdABB123460 ABB123460  <NA> 
#2  3464  ABB123461asjdjs  asjdjsABB123461 ABB123461  <NA> 
#3  7156  ABB123462ranogvmg  ranogvmgABB123462 ABB123462  <NA> 
#4  3171  ABB123463dkfohsd  dkfohsdABB123463 ABB123463  <NA> 
#5  5299  ABB123464fff///sss fff///sssABB123464 ABB123464  <NA> 
#6  4541   ABB123465jfsdf  jfsdfABB123465 ABB123465  <NA> 
#7  4956   ABB123466 sdf   sdfABB123466 ABB123466  <NA> 
#8  9926   ABB123467 sdf   sdfABB123467 ABB123467  <NA> 
#9  8418 ABB123468 fff///sss fff///sssABB123468 ABB123468  <NA> 
#10 1392   ABB123469 ty   tyABB123469 ABB123469  <NA> 
#11 9080 ABB123470 fff///sss fff///sssABB123470 ABB123470  <NA> 
#12 6455   ABB123471 dfs   dfsABB123471 ABB123471  <NA> 
#13 2423    ABB123472    ABB123472 ABB123472  <NA> 
#14 9101   ABB123473 gt   gtABB123473 ABB123473  <NA> 
#15 7807   ABB123474 y   yABB123474 ABB123474  <NA> 
#16 5195   ABB123475 f   fABB123475 ABB123475  <NA> 
#17 7827 ABB123476 gfgABB123462 ABB123462gfgABB123476 ABB123476 ABB123462 
#18  365   ABB123477 dsd   dsdABB123477 ABB123477  <NA> 
#19 9062   ABB123478 re   reABB123478 ABB123478  <NA> 
#20 5558   ABB123479 fgh   fghABB123479 ABB123479  <NA> 
#21  239   ABB123480 tu   tuABB123480 ABB123480  <NA> 
#22 8700   ABB123481 yu   yuABB123481 ABB123481  <NA> 
#23 6995   ABB123482 dfg   dfgABB123482 ABB123482  <NA> 
#24 9853   ABB123483 s   sABB123483 ABB123483  <NA> 
+0

Это работает, спасибо. Однако я хотел бы применить функцию str_extract_all ко всем другим столбцам в фрейме данных. В примере есть только 2 столбца, но мой больший набор данных равен 16. –

+0

@ KathleenBrannen Вы можете прокручивать столбцы и применять их. i.e 'lapply (examp, function (x) {lst <- str_extract_all (x, 'ABB [0-9] {6}'); ...' – akrun

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