使用apply()和ifelse()逐列比较两个data.frame并求和的实现问题
解决方案
核心思路
分两步实现需求:先对df1和df2的每一列组合做逐元素判断,再对判断结果求和整理成目标格式。
完整代码实现
# 示例数据 df1 <- data.frame(C1 = c("A", "B", "None"), C2 = c("B", "A", "A"), C3 = c("None", "None", "B"), row.names = paste0("Proj.", 1:3)) df2 <- data.frame(M1 = c("A", "None", "B"), M2 = c("B", "None", "B"), M3 = c("A", "B", "B"), M4 = c("None", "None", "None"), row.names = paste0("Proj.", 1:3)) # 生成最终结果 result <- sapply(df1, function(col_df1) { sapply(df2, function(col_df2) { # 逐元素判断:任一单元格为'None'返回0,否则返回1,再求和 sum(ifelse(col_df1 == "None" | col_df2 == "None", 0, 1)) }) }) # 转换为目标格式的DataFrame result_df <- as.data.frame(t(result)) rownames(result_df) <- colnames(df2) colnames(result_df) <- colnames(df1) # 查看结果 print(result_df)
代码说明
- 嵌套
sapply遍历列组合:外层遍历df1的每一列,内层遍历df2的每一列,对每一对列执行判断逻辑。 - 逐元素判断逻辑:用
ifelse直接检查元素是否为'None',只要任一元素是'None'就返回0,否则返回1。 - 求和与格式整理:对每一对列的判断结果求和,最后转置结果并设置行列名,匹配需求中的格式要求。
运行结果
C1 C2 C3 M1 1 1 0 M2 1 1 0 M3 2 2 1 M4 0 0 0
解决你之前的报错问题
你遇到的Error in ifelse(x == as.numeric(df2.2, 0, 1)) : 'list' object cannot be coerced to type 'double',原因是:
as.numeric仅接受一个待转换参数,你错误传入了0和1,导致返回结果为列表而非数值型向量。- 直接将
'None'转为0后,未正确处理列之间的逐元素比较逻辑,循环或向量操作逻辑混乱。
上面的代码通过直接在ifelse中判断'None',避免了类型转换的坑,同时用向量化操作替代低效循环,逻辑更清晰。
内容的提问来源于stack exchange,提问作者Purrsia
相关产品推荐
相关产品推荐

