为每一行提取满足特定条件的第一列

Extracting first column that meets certain criteria for each row

我会尽我所能解释我在做什么,这有点令人困惑,但我会试一试。基本上我从 2 个数据框开始。每个包含每个人的唯一行和每个用户两个项目作为列。我的目标是将其变成 1 个数据框,每个用户有一个唯一的行,并且在项目不重复的情况下,两个数据框中的第一个项目。例如,如果第一个数据框中的客户 1 他的项目是 "a" 和 "d",而在第二个数据框中他的项目是 "a" 和 "c",我想要该客户的最终数据框为 "a" 和 "c"。我已经编写了一个执行此操作的应用程序,但是当我对大约 160,000 行执行此操作时,它会花费相当多的时间。我希望有人能够提出更有效的解决方案来解决我的问题。

d1 <- data.frame(id = c("1", "2", "3"), stringsAsFactors = F)
r1 <- data.frame(i1 = c("a", "b", "c"), i2 = c("d", "e", "f"), stringsAsFactors = F)
rownames(r1) = d1$id
r2 <- data.frame(i1 = c("a", "c", "f"), i2 = c("c", "t", "l"), stringsAsFactors = F)
rownames(r2) = d1$id

dFinal <- data.frame(id = d1$id, r1 = "", r2 = "", stringsAsFactors = F)

dFinal$r1 = apply(dFinal, 1, function(x){r1[rownames(r1) == x["id"], "i1"]})
dFinal$r2 = apply(dFinal, 1, function(x){r2[rownames(r2) == x["id"], which(!r2[rownames(r2) == x["id"],c("i1","i2")] %in% x["r1"])[1]]})

以下是否符合您的要求:

# Keep only first column of first data.frame
df <- cbind(d1,r1,r2)[,-3]
names(df) <- c("id","r1_final","r2_i1","r2_i2")
df$r2_final <- df$r2_i1

# Keep only second column of second data.frame
# if the value in the first column is found in first data.frame
df[df$r1_final == df$r2_i1,"r2_final"] <- df[df$r1_final == df$r2_i1,"r2_i2"]
df_final <- df[,c("id","r1_final","r2_final")]
print(df_final)

  id r1_final r2_final
1  1        a        c
2  2        b        c
3  3        c        f

编辑: OP 要求一个解决方案,如果有四个 data.frames 而不是示例中的 2 个,这里是一些我没有测试过的代码,但它应该与两个额外的列一起使用

df$r2_final <- df$r2_i1
df$r3_final <- df$r3_i1
df$r4_final <- df$r4_i1

df[df$r1_final == df$r2_i1,"r2_final"] <- df[df$r1_final == df$r2_i1,"r2_i2"]
df[df$r3_i1 %in% c(df$r1_final,df$r2_final),"r3_final"] <- df[df$r3_i1 %in% c(df$r1_final,df$r2_final),"r3_i2"]
df[df$r4_i1 %in% c(df$r1_final,df$r2_final,df$r3_final),"r4_final"] <- df[df$r4_i1 %in% c(df$r1_final,df$r2_final,df$r3_final),"r4_i2"]
df_final <- df[,c("id","r1_final","r2_final","r3_final","r4_final")]

感谢您接受的答案,因为它工作得很好!然而,它给了我使用 ifelse 的想法。虽然它不会比接受的答案好或坏,但在添加更多列或数据框时,我更容易思考。

  dfInt <- cbind(df1, df2, df3, df4)
  dfInt$R1_Final <- dfInt$R1_1
  dfInt$R2_Final <- ifelse(dfInt$R1_Final == dfInt$R2_1,
                               dfInt$R2_2,
                               dfInt$R2_1)
  dfInt$R3_Final <- ifelse(dfInt$R1_Final != dfInt$R3_1 & dfInt$R2_Final != dfInt$R3_1,
                               dfInt$R3_1,
                               ifelse(dfInt$R2_Final != dfInt$R3_2,
                                      dfInt$R3_2,
                                      dfInt$R3_3))
  dfInt$R4_Final <- ifelse(dfInt$R1_Final != dfInt$R4_1 & dfInt$R2_Final != dfInt$R4_1 & dfInt$R3_Final != dfInt$R4_1,
                               dfInt$R4_1,
                               ifelse(dfInt$R2_Final != dfInt$R4_2 & dfInt$R3_Final != dfInt$R4_2,
                                      dfInt$R4_2,
                                      ifelse(dfInt$R3_Final != dfInt$R4_3,
                                             dfInt$R4_3,
                                             dfInt$R4_4)))