我有3个数据帧。第一个数据帧(例如df1)具有多个行和列。第二个数据帧和第三个数据帧(例如df2和df3)只有一行,并且只有df1的列子集。 df2和df3中的列名称相同。所以我想做的是将df1中的每一行与df2和df3中的单行进行比较。如果来自df1的单元格的值与df2的单元格内容匹配,则将df1中的单元格的值替换为1,如果来自df1的单元格的值与df3匹配,则将df1中的单元格的值替换为2和如果df2的单元格内容与df2或df3不匹配,请用-替换df1中的单元格值。我编写了一个循环来执行此操作,但是速度很慢。我想知道是否有任何优化的方法来做到这一点。谢谢。
以下是示例数据帧和预期的输出:
df1
c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12
q w e r t y q w e r t y
q e r t y q e r e r t y
w e r t y t q w e r w t
df2
c5 c6 c7 c8 c9 c10 c11 c12
t y q w e t w t
df3
c5 c6 c7 c8 c9 c10 c11 c12
y q q t e r t t
Expected output:
c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12
q w e r 1 1 1 1 1 2 2 -
q e r t 2 2 - - 1 2 2 -
w e r t 2 - 1 1 1 2 1 1
答案 0 :(得分:0)
我们可以通过复制'df2'和'df3'的行来创建一对逻辑矩阵,同时仅选择与'df2'或'df3'相同的df1列,然后将值组合为一个逐步进行逻辑比较
i1 <- df1[names(df2)] == df2[rep(1, nrow(df1)),]
i2 <- df1[names(df3)] == df3[rep(1, nrow(df1)),]
df1[names(df3)] <- ((!i1 & i2) + 1) * NA^(!i1 & !i2)
df1
# c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12
#1 q w e r 1 1 1 1 1 2 2 NA
#2 q e r t 2 2 NA NA 1 2 2 NA
#3 w e r t 2 NA 1 1 1 2 1 1
最好使用NA
而不是-
,因为-
可以将列类型从numeric
更改为character
df1 <- structure(list(c1 = c("q", "q", "w"), c2 = c("w", "e", "e"),
c3 = c("e", "r", "r"), c4 = c("r", "t", "t"), c5 = c("t",
"y", "y"), c6 = c("y", "q", "t"), c7 = c("q", "e", "q"),
c8 = c("w", "r", "w"), c9 = c("e", "e", "e"), c10 = c("r",
"r", "r"), c11 = c("t", "t", "w"), c12 = c("y", "y", "t")), class = "data.frame", row.names = c(NA,
-3L))
df2 <- structure(list(c5 = "t", c6 = "y", c7 = "q", c8 = "w", c9 = "e",
c10 = "t", c11 = "w", c12 = "t"), class = "data.frame", row.names = c(NA,
-1L))
df3 <- structure(list(c5 = "y", c6 = "q", c7 = "q", c8 = "t", c9 = "e",
c10 = "r", c11 = "t", c12 = "t"), class = "data.frame", row.names = c(NA,
-1L))
答案 1 :(得分:0)
我们可以使用intersect
找到常见的列。重复df2
和df3
的行,并将其与df1
进行比较,并将df1
中的匹配值替换为1,将df2
的匹配值替换为2,并替换所有其他值由"-"
。
cols <- intersect(names(df1), names(df2))
df1[cols][df1[cols] == df2[rep(seq_len(nrow(df2)), nrow(df1)), ]] <- 1
df1[cols][df1[cols] == df3[rep(seq_len(nrow(df3)), nrow(df1)), ]] <- 2
df1[cols][(df1[cols] != 1) & (df1[cols] != 2)] <- "-"
df1
# c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12
#1 q w e r 1 1 1 1 1 2 2 -
#2 q e r t 2 2 - - 1 2 2 -
#3 w e r t 2 - 1 1 1 2 1 1
基于注释,如果我们要填充df1
和df2
中不存在的df3
中的剩余值,我们可以找出不匹配的索引并使用{{1} }将值粘贴在一起。
paste0