2017-07-18 1 views
0

私は2つのデータフレームstu1とstu2を持っています。両方とも一致するID列を持ちますが、他の列では変数が異なります。例えばrデータを2つのデータフレームに一致させ、一致する行の別の列にあるテキストをチェックします。

stu1

ID, Grade, Group, Age 
ad1, A, Green, 14 
bc1, B, Green, 13 
cd1, B, Blue, 14 
fs3, C, Red, 13 

stu2:私は何をしようとしている

ID, Prog, Loc, Year 
bc1, LSC1, Ext, 2013 
cd1, LSC1, Ext, 2013 
cd1, BSC1, Int, 2013 
ad1, BSC2, Int, 2012 
rs2, KHL4, Ext, 2014 

は、別のテキストかどうかをチェックしstu1の学生のIDがstu2内に存在するかどうかをチェックしています対応する行の列は私の文字列と一致します。 Prog =='BSC*'stu1に "Yes"または "No"という新しい列を作成します。

ので、stu1のための結果は次のようになります。

ID, Grade, Group, Age, BSCProg 
ad1, A, Green, 14, Yes 
bc1, B, Green, 13, No 
cd1, B, Blue, 14, Yes 
fs3, C, Red, 13, No 

私は例えば、失敗した多くの様々な方法を試してみた:

stu1$BSCProg <- ifelse(stu2[grepl("BSC", stu2$Prog) & match(paste0(stu1$ID), 
    paste0(stu1$ID)),], "Yes", "No") 

stu1$BSCProg <- ifelse(is.na(match(paste0(stu1$ID), 
    paste0(stu2$ID) & stu2[grepl("BSC", stu2$Prog),])),"No","Yes") 

stu1$BSCProg <- ifelse(stu1$ID %in% stu2$ID & grepl('BSC', stu2$Prog), "Yes", "No") 

答えて

4

あなたは列の比較を行うことができるように、私は2つのテーブルをマージすることでこれを行うだろう。

library(data.table) 

setDT(stu1) 
setDT(stu2) 

dat <- merge(stu1, 
      stu2[Prog %like% "BSC", .(ID, BSCProg = Prog)], 
      by = "ID", 
      all.x = TRUE) 

dat[, BSCProg := ifelse(is.na(BSCProg), "No", "Yes")] 

結果:data.table使用ビットこと

#  ID Grade Group Age BSCProg 
# 1: ad1  A Green 14  Yes 
# 2: bc1  B Green 13  No 
# 3: cd1  B Blue 14  Yes 
# 4: fs3  C Red 13  No 

開梱を、最初のステップは、stu1stu2からIDProg列をマージすることです。 Prog %like% "BSC"セクションでは、Prog列の値に「BSC」が含まれている行のみがマージされます。 BSCProg = Progは、最後に必要な列に列の名前を変更することです。

これが行われると、列の値はNAまたはBSC1,BSC2のような値になります。最後の文BSCProg := ifelse(is.na(BSCProg), "No", "Yes")NAを「いいえ」に変更し、それ以外の場合は「はい」にします。

+1

シンプルで、 '%like% 'の+1です! – juan

+0

ありがとうございました!それはすごく素早く、助けてくれました!あなたは素晴らしかった:-) – Leila

+0

これは本当にありがとう!私は今、すべてのプログラム用に新しい列を作成するように求められてきました。 5つのプログラムしかないので、コードをコピー&ペーストして検索を変更し、毎回新しい列を追加することができました。他のプログラム(LSC、BSC 1&2、KHL1:4)を検索する列を追加する方がシンプルでクリーンな方法がありますか?私は既存の提案で遊んでみましたが、すべて失敗しました。 – Leila

1

あなたはmergeID最初で、その後、作成することができます新しい列。ここdata.table解決策は以下のとおりです。

library(data.table) 
setDT(stu1, key="ID") 
setDT(stu2, key="ID") 
stu1 = merge(stu1, stu2, all.x=TRUE) 
stu1[, BSCProg:=ifelse(grepl("^BSC", Prog), "Yes", "No")] 
+1

私と同じように、私はそれもやったのです。問題は 'stu2'で、ID列に' cd1'の繰り返しがあるので、マージ 'stu1'の後に行が得られ、' BSCProg'という2つの値があります。 –

+0

良いキャッチ!私はサンプルデータを試してみたはずです! – juan

+0

これもお試しいただきありがとうございます!これは元のデータに余分な行を追加する必要がある場合に役立つかもしれません(まだ尋ねられていませんが、あまりにも上がっても驚かないでしょう)。乾杯! – Leila

0

dplyrおよびtidyr溶液。 stu3が最終出力です。

library(dplyr) 
library(tidyr) 

stu1 <- data_frame(ID = c("ad1", "bc1", "cd1", "fs3"), 
        Grade = c("A", "B", "B", "C"), 
        Group = c("Green", "Green", "Blue", "Red"), 
        Age = c(14, 13, 14, 13)) 

stu2 <- data_frame(ID = c("bc1", "cd1", "cd1", "ad1", "rs2"), 
        Prog = c("LSC1", "LSC1", "BSC1", "BSC2", "KHL4"), 
        Loc = c("Ext", "Ext", "Int", "Int", "Ext"), 
        Year = c(2013, 2013, 2013, 2012, 2014)) 


stu3 <- stu1 %>% 
    full_join(stu2 %>% select(ID, Prog), by = "ID") %>% 
    mutate(BSCProg = ifelse(grepl("BSC", Prog), "Yes", "No")) %>% 
    drop_na(Grade) %>% 
    select(-Prog) %>% 
    group_by(ID) %>% 
    arrange(desc(BSCProg)) %>% 
    slice(1) 
+0

'full_join'よりも' left_join'はここでよかったですか? – CPak

+0

@ChiPak 'stu2'は' cd1'のように 'ID'を複製しています。 'left_join'は重複した行を失います。 – www

+0

'left_join(stu1、select(stu2、ID、Prog)、by =" ID ")'は 'cd1'を保持します。とにかく、ちょっとした提案。 – CPak

関連する問題