在R语言中如何逐行比较两个DataFrame的数值并生成二值结果表
这个问题的核心是R中向量和矩阵/数据框比较时的循环补齐规则——默认是按列循环,而你需要的是按行循环比较。你的原始代码之所以得到全1,是因为R把mydata$value按列重复到和rntable同维度,导致比较逻辑完全不符合你的需求。
下面给你几种简洁的实现方法,都是逐行对应比较的:
方法1:利用矩阵广播(最简洁)
把mydata$value转换成和rntable同维度的矩阵,其中每一行都是相同的value值,这样就能直接对应逐行比较:
# 将value转成50行100列的矩阵(每一行重复100次) val_mat <- matrix(mydata$value, nrow = nrow(rntable), ncol = ncol(rntable), byrow = FALSE) # 逐行比较生成结果 result <- as.data.frame(ifelse(rntable < val_mat, 0, 1))
或者更简洁的写法,用rep函数按行重复value:
result <- as.data.frame(ifelse(rntable < rep(mydata$value, each = ncol(rntable)), 0, 1))
这里rep(..., each = ncol(rntable))会把每个value重复100次,刚好匹配rntable的每行100个元素的结构。
方法2:用apply逐行处理
apply函数的MARGIN=1参数可以让我们对每一行单独操作:
# 按行遍历rntable,每行和对应行的value比较 result_matrix <- t(apply(rntable, 1, function(row_val, ref_val) { as.integer(row_val >= ref_val) }, ref_val = mydata$value)) # 转成数据框 result <- as.data.frame(result_matrix)
注意这里用t()转置结果,因为apply默认会把每行的结果作为列返回,转置后才和原表结构一致。
方法3:用dplyr的行操作(适合tidyverse用户)
如果你习惯用tidyverse工具链,可以用rowwise()实现逐行处理:
library(dplyr) result <- rntable %>% rowwise() %>% # 对所有列执行比较:当前列元素 >= 对应行的value则为1,否则0 mutate(across(everything(), ~ as.integer(.x >= mydata$value[cur_row()]))) %>% ungroup()
rowwise()会让后续的操作按行执行,cur_row()获取当前行号,精准匹配mydata$value的对应元素。
验证示例(匹配你提供的测试数据)
比如你的示例中:
- mydata第1行value=0.59057316
- rntable第1行v1=0.21092575(<0.59,输出0),v2=0.68144251(>0.59,输出1),v3=0.26929378(<0.59,输出0),v4=0.34583023(<0.59,输出0)
用上面任意一种方法都会得到你想要的0 1 0 0的结果,完全符合需求。
内容的提问来源于stack exchange,提问作者Baldy
相关产品推荐
相关产品推荐

