在R语言中如何比较两个数据表对应值并返回最大值?
如何逐行比较两个data.frame对应列的值并取最大值
你有两个data.frame dat1 和 dat2,希望比较两者同名列的对应值,返回每行的最大值。数据如下:
library(reshape2) dat1 <- data.frame(sn=c("v1","v2"), A=c(1,0), B=c(0,1), C=c(0,0), D=c(1,0)) dat2 <- data.frame(sn=c("v1","v2", "v3"), A=c(1,0,1), C=c(1,0,1), B=c(0,0,1))
dat1 内容:
sn A B C D v1 1 0 0 1 v2 0 1 0 0
dat2 内容:
sn A C B v1 1 1 0 v2 0 0 0 v3 1 1 1
你尝试了以下代码,但结果不符合预期:
dt1 <- melt(dat1,"sn") dt2 <- melt(dat2,"sn") dt3 <- merge(dt1,dt2,by=c("sn","variable")) dt3$value <- max(dt3$value.x, dt3$value.y)
错误结果:
sn variable value.x value.y value v1 A 1 1 1 v1 B 0 0 1 v1 C 0 1 1 v2 A 0 0 1 v2 B 1 0 1 v2 C 0 0 1
期望的正确结果:
sn variable value.x value.y value v1 A 1 1 1 v1 B 0 0 0 v1 C 0 1 1 v2 A 0 0 0 v2 B 1 0 1 v2 C 0 0 0
问题原因
你的代码出错的核心原因是 max() 函数会计算两个向量的全局最大值,而不是逐行比较对应位置的元素。所以最终所有行的value都被赋值为整个value.x和value.y向量中的最大值1,而非每行的局部最大值。
修正方案
要实现逐行取最大值,需要使用 pmax() 函数——它会对输入的向量进行并行元素级比较,返回每个位置的最大值。
修正后的代码
library(reshape2) dat1 <- data.frame(sn=c("v1","v2"), A=c(1,0), B=c(0,1), C=c(0,0), D=c(1,0)) dat2 <- data.frame(sn=c("v1","v2", "v3"), A=c(1,0,1), C=c(1,0,1), B=c(0,0,1)) dt1 <- melt(dat1,"sn") dt2 <- melt(dat2,"sn") dt3 <- merge(dt1,dt2,by=c("sn","variable")) # 用pmax替代max,实现逐行取最大值 dt3$value <- pmax(dt3$value.x, dt3$value.y)
运行后得到的正确结果:
sn variable value.x value.y value 1 v1 A 1 1 1 2 v1 B 0 0 0 3 v1 C 0 1 1 4 v2 A 0 0 0 5 v2 B 1 0 1 6 v2 C 0 0 0
可选:dplyr语法实现
如果你习惯用dplyr的管道式语法,也可以这样写:
library(dplyr) dt3 <- dt3 %>% mutate(value = pmax(value.x, value.y))
内容的提问来源于stack exchange,提问作者Ridwan Shittu
相关产品推荐
相关产品推荐

