2017-09-07 3 views
1

列の各行(letter_strings)に、可変数の文字列がカンマで区切られているとします。たとえば:Rのデータフレーム:カンマで区切られたセル内の複数の文字列を参照

letter_strings 

abc, def, ghi, jkl 
mno, pqr 
stu, vw, xyz 

私はデータフレーム内の各文字列を検索したいと思います:

letter_strings code 

abc YES 
def NO 
ghi MAYBE 
jkl SURE 
mno PERHAPS 
pqr ALWAYS 
stu NEVER 
vw NOGO 
xyz ABSENT 

と、次の対応する行を取得し、追加の列

YES, NO, MAYBE, SURE 
PERHAPS, ALWAYS 
NEVER, NOGO, ABSENT 

にでこれが可能ですR、私は本当にこの問題に取り組む方法を知らない...

ありがとうございます!

+3

あなたの質問の体内で、あなたのデータの 'dput'を入力してください。作業しているデータの実際の構造を判断することは役に立ちます。それが大きければ、 'dput(head(dat、10))'程度で十分です。 – lmo

答えて

0

W

あまりにも多くの文字列が存在しない場合は、ループ内でgsubでこれを行うことができます。それは、ルックアップの名前で)、すなわち単語文字のシーケンス"\\w+"する定義された正規表現(ここでは、へのマッチを見上げ以外

Temp = letter_strings 
for(i in 1:nrow(df)) { 
    Temp = gsub(df$letter_strings[i], df$code[i], Temp) } 
Temp 
[1] "YES, NO, MAYBE, SURE" "PERHAPS, ALWAYS"  "NEVER, NOGO, ABSENT" 
3

1)gusbfn

gsubfngsubのようなものですリストlookupで、ターゲット文字列内の名前をlookupの値に置き換えます。

library(gsubfn) 

lookup <- with(DF2, as.list(setNames(code, letter_strings))) 
transform(DF1, codes = gsubfn("\\w+", lookup, letter_strings)) 

与える:

 letter_strings    codes 
1 abc, def, ghi, jkl YES, NO, MAYBE, SURE 
2   mno, pqr  PERHAPS, ALWAYS 
3  stu, vw, xyz NEVER, NOGO, ABSENT 

2)dplyr/tidyr DF2でそれに参加して、元の形に戻ってそれを再構築、長いフォームにDF1を変換します

library(dplyr) 
library(tidyr) 

DF1 %>% 
    mutate(id = 1:n()) %>% 
    separate_rows(letter_strings) %>% 
    left_join(DF2) %>% 
    group_by(id) %>% 
    summarise(letter_string = toString(letter_strings), codes = toString(code)) %>% 
    ungroup %>% 
    select(-id) 

与える:

Joining, by = "letter_strings" 
# A tibble: 3 x 2 
     letter_string    codes 
       <chr>    <chr> 
1 abc, def, ghi, jkl YES, NO, MAYBE, SURE 
2   mno, pqr  PERHAPS, ALWAYS 
3  stu, vw, xyz NEVER, NOGO, ABSENT 

3)strsplit/merge/aggregatestrsplitを使用して、DF1stackの文字列を長いフォームに分割するst。次にで、DF2aggregateが元の形式に戻ります。パッケージは使用されません。

s <- strsplit(DF1$letter_strings, ", ") 
st <- stack(setNames(s, seq_along(s))) 
m <- merge(st, DF2, by = 1, all.x = TRUE, all.y = FALSE) 
aggregate(. ~ ind, m, toString)[-1] 

与える:

   values     code 
1 abc, def, ghi, jkl YES, NO, MAYBE, SURE 
2   mno, pqr  PERHAPS, ALWAYS 
3  stu, vw, xyz NEVER, NOGO, ABSENT 

3A)magrittrこの表現することができる使用magrittr:

library(magrittr) 

DF1 %>% 
    "$"("letter_strings") %>% 
    strsplit(", ") %>% 
    setNames(seq_along(.)) %>% 
    stack %>% 
    merge(DF2, by = 1, all.x = TRUE, all.y = FALSE) %>% 
    aggregate(. ~ ind, ., toString) %>% 
    "["(-1) 


s <- stack(setNames(strsplit(DF1$letter_strings, ", "), 1:nrow(DF1))) 
m <- merge(s, DF2, by = 1, all.x = TRUE, all.y = FALSE) 
aggregate(. ~ ind, m, toString)[-1] 

4)data.tableなお、その下のコメントで@ Uweは、(2)および(3)のアプローチのdata.tableバージョンを提供しました。これは、ロングフォームに変換し、結合して変換しますバック。

注:再現可能な形で入力:

Lines1 <- " 
letter_strings 
abc, def, ghi, jkl 
mno, pqr 
stu, vw, xyz" 
DF1 <- read.table(text = Lines1, header = TRUE, as.is = TRUE, sep = ";") 

Lines2 <- " 
letter_strings code 
abc YES 
def NO 
ghi MAYBE 
jkl SURE 
mno PERHAPS 
pqr ALWAYS 
stu NEVER 
vw NOGO 
xyz ABSENT" 
DF2 <- read.table(text = Lines2, header = TRUE, as.is = TRUE) 
+0

ありがとう!あなたのソリューションは、私が必要とするものに最適です! –

+0

* reshapeの 'data.table'バージョンをlongに追加したい場合は、結合して、wide *:' library(data.table);に戻ってください。 setDT(DF1); setDT(DF2); DF2 [、rn:= .I] [、strsplit(文字ストリング、 "、固定= TRUE)、by = rn]、on =。(文字列= V1)[、lapply(.SD、toString)、 by = rn] [、 - "rn"] ' – Uwe

関連する問題