tidyverse中mutate分组计算minAB0结果不符预期的问题
分组计算逐行最小值结果异常问题
问题描述
我尝试用mutate()按Sample分组,计算每行的minAB0列,代码如下:
data <- data %>% group_by(Sample) %>% mutate(minAB0 = min(XD_VD+SE, value))
但输出结果不符合预期。手动逐行计算的结果为:
min((data$XD_VD[1] + data$SE[1]), data$value[1]) = 29 min((data$XD_VD[2] + data$SE[2]), data$value[2]) = 36.71198
而用tidyverse分组计算后,Sample=1的所有minAB0值都是26,Sample=2的所有minAB0值都是32.98313,和手动计算结果不符。
所用数据:
data <- structure(list(Sample = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), XD_VD = c(35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 35.9419827146857, 32.1823275467508, 32.1823275467508, 32.1823275467508, 32.1823275467508, 32.1823275467508, 32.1823275467508, 32.1823275467508, 32.1823275467508, 32.1823275467508, 32.1823275467508), SE = c(0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.77, 0.8008, 0.8008, 0.8008, 0.8008, 0.8008, 0.8008, 0.8008, 0.8008, 0.8008, 0.8008), value = c(29, 49, 44, 50, 37, 40, 50, 56, 65, 93, 87, 49, 46, 57, 39, 44, 26, 30, 45, 44, 98, 70, 59, 70, 77, 55, 50, 33, 58, 71, 68)), row.names = c(NA, -31L), class = c("tbl_df", "tbl", "data.frame"))
原因分析
你使用的min(XD_VD+SE, value)逻辑错误:在分组环境中,XD_VD+SE会生成当前分组的所有行计算结果的向量,value也是当前分组的所有行值的向量,min()函数会将这两个向量合并后取全局最小值,而非逐行比较两个位置的数值取最小。
- 对
Sample=1,value列的最小值是26,因此整个分组的minAB0都被设为26; - 对
Sample=2,XD_VD+SE的计算值为32.1823275+0.8008=32.98313,这是该分组中这个计算值的最小值,因此整个分组的minAB0都被设为这个数。
解决方法
要实现逐行取两个值的最小值,需使用pmin()函数——它会对两个向量进行逐元素比较,返回每个位置的最小值。修改后的代码如下:
data <- data %>% group_by(Sample) %>% mutate(minAB0 = pmin(XD_VD + SE, value))
运行后即可得到与手动计算一致的结果,比如第一行minAB0为29,第二行为36.71198。
内容的提问来源于stack exchange,提问作者ksinva
相关产品推荐
相关产品推荐

