Rifelse基于满足两个条件的观察

时间:2019-06-21 18:44:38

标签: r if-statement

是的,这确实是一个非常简单的问题,因为我知道这是一种合乎逻辑的方法,这只会使我陷入困境。我有两个数据帧,并希望在第一个数据帧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)

3 个答案:

答案 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)

此处pasteinteraction具有相同的作用。它将两列连接在一起,形成一个向量。

do.call(paste, df.ex1[,1:2])
#"sally A" "joe B"   "ben F"   "nick A"