r匹配两个数据帧中的数据,然后检查另一列中的文本以查找匹配的行

时间:2017-07-18 13:23:32

标签: r if-statement match grepl

我有两个数据帧stu1和stu2。两者都有匹配的ID列,但在其他列中有不同的变量。

例如,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中是否存在stu2中的学生ID,然后检查相应行的另一列中的文字是否与我的字符串匹配,例如Prog =='BSC*'然后在stu1中创建一个新列,其中显示“是”或“否”。

因此,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")

3 个答案:

答案 0 :(得分:4)

我会通过合并两个表来执行此操作,以便您可以进行列比较。使用data.table

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

结果:

#     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

解压缩一点,第一步是将ID中的Progstu2列合并到stu1Prog %like% "BSC"部分仅合并Prog列具有“BSC”的行作为值的一部分。 BSCProg = Prog是将列重命名为您想要的内容。

完成此操作后,列的值将为NABSC1BSC2等值。最终声明BSCProg := ifelse(is.na(BSCProg), "No", "Yes")会将任何NA更改为“否”,并将其他任何内容改为“是”。

答案 1 :(得分:1)

您可以先merge ID,然后创建新列。这是一个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")]

答案 2 :(得分:0)

dplyrtidyr解决方案。 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)