基于共享列匹配DF2的new_var至DF1时结果全为0的问题排查
问题原因与解决办法
你原代码的核心错误是括号位置不对:which(col1 == df2$col1) & (col2 == df2$col2) 里,你把which只套在了第一个条件外,导致实际是用第一个条件的索引结果和第二个条件的布尔值做与运算,逻辑完全错了,自然找不到匹配项,返回长度0。
但更合理的做法根本不用rowwise(),用数据框连接的方式更高效直观,以下是具体方案:
方案1:左连接(推荐)
因为DF2里同一col1+col2组合的new_var值是重复的(比如A+C全是1,A+D全是3),先给DF2去重,再和DF1做左连接,直接把对应的值匹配过来:
library(dplyr) # 先给DF2去重,保留每个col1+col2对应的new_var值 df2_clean <- df2 %>% distinct(col1, col2, new_var) # 左连接DF1和处理后的DF2 df1_result <- df1 %>% left_join(df2_clean, by = c("col1", "col2"))
运行后得到的结果:
col1 col2 col3 col4 new_var 1 A C 22 NA 1 2 B D 58 NA NA 3 A E 35 NA NA 4 B C 86 NA NA 5 A D 37 NA 3 6 B E 16 NA NA 7 A C 46 NA 1 8 B D 23 NA NA 9 A E 88 NA NA 10 B C 3 NA NA
方案2:修正原代码逻辑(不推荐,效率低)
如果非要用你原来的思路,把两个条件都放进which里就行:
df1 %>% rowwise() %>% mutate(new_var = length(df2$new_var[which(col1 == df2$col1 & col2 == df2$col2)]))
但这种逐行循环的方式在数据量大的时候会很慢,不建议用。
补充:如果要统计匹配行数
要是你的需求不是取new_var的值,而是统计DF2里每个col1+col2组合的出现次数,可以这样做:
df2_count <- df2 %>% count(col1, col2, name = "new_var") df1_result <- df1 %>% left_join(df2_count, by = c("col1", "col2"))
结果里A+C的new_var会是3,A+D的new_var会是3,其他没有匹配的则为NA。
内容的提问来源于stack exchange,提问作者HPham
相关产品推荐
相关产品推荐

