r 匹配两个数据框中的数据,然后检查另一列中的文本是否匹配行
r match data in two data frames then check text in another column for matched row
我有两个数据帧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
中的学生 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")
您可以先 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")]
我会通过合并两个表来完成此操作,以便您可以进行列比较。使用 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
稍微解压一下,第一步是将 stu2
中的 ID
和 Prog
列合并到 stu1
中。 Prog %like% "BSC"
部分将仅合并那些 Prog
列具有 "BSC" 作为值的一部分的行。 BSCProg = Prog
最后就是把列重命名为你想要的。
完成后,该列的值将是 NA
或类似 BSC1
、BSC2
的值。最后的语句 BSCProg := ifelse(is.na(BSCProg), "No", "Yes")
会将任何 NA
更改为 "No" 并将其他任何内容更改为 "Yes".
一个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)
我有两个数据帧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
中的学生 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")
您可以先 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")]
我会通过合并两个表来完成此操作,以便您可以进行列比较。使用 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
稍微解压一下,第一步是将 stu2
中的 ID
和 Prog
列合并到 stu1
中。 Prog %like% "BSC"
部分将仅合并那些 Prog
列具有 "BSC" 作为值的一部分的行。 BSCProg = Prog
最后就是把列重命名为你想要的。
完成后,该列的值将是 NA
或类似 BSC1
、BSC2
的值。最后的语句 BSCProg := ifelse(is.na(BSCProg), "No", "Yes")
会将任何 NA
更改为 "No" 并将其他任何内容更改为 "Yes".
一个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)