是的,这确实是一个非常简单的问题,因为我知道这是一种合乎逻辑的方法,这只会使我陷入困境。我有两个数据帧,并希望在第一个数据帧0/1中创建新列,具体取决于第二个数据帧中的任何行是否包含第一个的col1 / col2对。
数据
df.ex1 <- data.frame('name'=c('sally', 'joe', 'ben', 'nick'), 'grade1'=c('A', 'B', 'F', 'A'))
df.ex2 <- data.frame('name'=c('jed', 'ben', 'sally', 'nick'), 'grade1'=c('A', 'F', 'A', 'C'))
> df.ex1
name grade1
1 sally A
2 joe B
3 ben F
4 nick A
> df.ex2
name grade1
1 jed A
2 ben F
3 sally A
4 nick C
#Expected result:
name grade1 bin
1 sally A 1
2 joe B 0
3 ben F 1
4 nick A 0
显而易见的方法是检查第二个df中是否存在名称/等级对:
df.ex1$bin <- ifelse(df.ex1[,1:2] %in% df.ex2[,1:2], 1, 0)
但这不起作用。为什么不?正确的方法是什么?实际上,什么是得出正确方法的正确思维过程?
注意,这显然行不通:
df.ex1$bin <- ifelse(df.ex1[,1] %in% df.ex2[,1] & df.ex1[,2] %in% df.ex2[,2], 1, 0)
答案 0 :(得分:3)
您可能正在首先基于联接寻找内容:
df.ex2$bin <- 1
res <- merge(df.ex1,df.ex2,all.x = TRUE)
res$bin <- ifelse(is.na(res$bin),0,1)
> res
name grade1 bin
1 ben F 1
2 joe B 0
3 nick A 0
4 sally A 1
使用其他常见的软件包(例如 dplyr 或 data.table )可以有很多等效的方法。
答案 1 :(得分:1)
您可以使用data.table“更新联接”
library(data.table)
setDT(df.ex1)
setDT(df.ex2)
df.ex1[, bin := 0]
df.ex1[df.ex2, on = .(name, grade1), bin := 1]
df.ex1
# name grade1 bin
# 1: sally A 1
# 2: joe B 0
# 3: ben F 1
# 4: nick A 0
答案 2 :(得分:1)
您可以将两列与interaction
结合在一起,然后像完成操作一样使用%in%
:
df.ex1$bin <- ifelse(interaction(df.ex1[,1:2]) %in% interaction(df.ex2[,1:2]), 1, 0)
df.ex1
# name grade1 bin
#1 sally A 1
#2 joe B 0
#3 ben F 1
#4 nick A 0
在这种情况下, interaction
将两列的因子合并,例如,由df.ex1[,1:2]
一起构成一个向量。
df.ex1[,1:2] #gives you a data.frame
# name grade1
#1 sally A
#2 joe B
#3 ben F
#4 nick A
interaction(df.ex1[,1:2]) #gives you a factor
#sally.A joe.B ben.F nick.A
然后将这两个因子/向量应用于%in%
。
或者,您可以像这样使用paste
:
ifelse(do.call(paste, df.ex1[,1:2]) %in% do.call(paste, df.ex2[,1:2]), 1, 0)
此处paste
与interaction
具有相同的作用。它将两列连接在一起,形成一个向量。
do.call(paste, df.ex1[,1:2])
#"sally A" "joe B" "ben F" "nick A"