R语言矩阵子集化问题:分步获取第三列最大值所在行失效的原因咨询
问题解析:浮点数精度导致的相等判断失效
这其实是浮点数精度问题在搞鬼,我来给你拆解清楚:
核心原因:浮点数的不精确存储
在R(以及大多数编程语言)中,像-1563.41这样的十进制小数,在底层是以二进制浮点数存储的,这个过程会产生微小的精度损失。你看到的max(results[,3])返回值表面是-1563.41,但实际存储的是一个更精确的近似值(比如可能是-1563.4099999999998或者-1563.4100000000002)。
当你手动输入-1563.41或者把它放在引号里转成字符再转回数值时,得到的是另一个近似值,和max(results[,3])的实际返回值在底层存在细微差异,所以==的严格相等判断会返回FALSE,自然找不到你想要的行。
为什么嵌套max()就有效?
当你写成results[results[,3] == max(results[,3]),]时,你是直接用max()返回的精确浮点数去做比较,这个数值和矩阵中对应行的第三列值是完全一致的(没有手动输入的二次近似),所以相等判断能正确命中目标行。
转成dataframe或用tidyverse失败的原因
本质还是同一个问题:你依然在用手动输入的-1563.41(一个近似值)去和矩阵/数据框中存储的精确浮点数做比较,精度不匹配导致筛选条件不成立。
解决方案
推荐方案:直接使用
max()的返回值
就像你成功的代码那样,直接嵌套使用max(),避免手动输入带来的精度误差:results[results[,3] == max(results[,3]),]使用近似相等判断
如果需要单独存储最大值再做筛选,可以用all.equal()函数判断浮点数是否近似相等:target_max <- max(results[,3]) results[sapply(results[,3], function(x) isTRUE(all.equal(x, target_max))), ]如果你习惯用tidyverse,可以用
dplyr::near()函数(专门处理浮点数近似相等):library(dplyr) as.data.frame(results) %>% filter(near(V3, max(V3)))
内容的提问来源于stack exchange,提问作者mbuta
相关产品推荐
相关产品推荐

