R语言subset筛选返回空data.frame问题求助
R语言浮点数比较异常问题排查
问题现象
- 生成模拟数据集代码:
z2 <- data.frame(a=rep(1:120,100), b=rep(rep(c(0,1),each=120),50), c=rep(rep(c(0,1),each=240),25), d=rep(rep(seq(.1,2.5,.1),each=120),4)) - 执行
subset(z2,d==1.5)筛选d等于1.5的子集,得到空数据框:[1] a b c d
<0 rows> (or 0-length row.names) - 直接查看行
z2[7750,]显示d值为1.5,但table(z2$d==1.5)结果全为FALSE(共12000条)。
问题原因
这是浮点数精度误差导致的。R用二进制存储浮点数,seq(.1,2.5,.1)生成的序列里,看似为1.5的数值,实际是接近1.5但存在微小偏差的二进制浮点数(比如1.50000000000001或1.49999999999999)。直接用==做精确比较时,微小偏差会导致判断结果为FALSE。
你可以执行sprintf("%.20f", z2$d[7750])验证,会看到该数值的真实精度表示并非严格的1.5。
解决方法
- 使用
all.equal()函数:该函数会考虑浮点数的微小误差,判断数值是否在允许的误差范围内相等:subset(z2, sapply(d, function(x) isTRUE(all.equal(x, 1.5)))) - 设置误差容忍阈值:直接判断数值是否在1.5的极小误差范围内:
subset(z2, abs(d - 1.5) < 1e-10) - 生成无误差的序列:用整数序列结合除法生成精确的十进制数值:
d_seq <- seq.int(1, 25, 1)/10 z2 <- data.frame(a=rep(1:120,100), b=rep(rep(c(0,1),each=120),50), c=rep(rep(c(0,1),each=240),25), d=rep(rep(d_seq,each=120),4))
内容的提问来源于stack exchange,提问作者Giuseppe Marano
相关产品推荐
相关产品推荐

