R语言使用readxl包导入Excel时数值出现微小偏差问题求助
问题原因
这是双精度浮点数的固有存储特性导致的,并非readxl包导入错误:
- Excel存储数值采用8字节双精度浮点数格式,但软件界面展示、内置计算时会自动对数值做截断处理,你在Excel单元格里看到的
23923.72846564920000000并非内存中存储的真实二进制值,只是截断到15位有效数字后的显示结果。 readxl导入数据时会直接读取xlsx文件内存储的原始二进制浮点值,不会做Excel层面的显示截断;而R默认展示浮点数时会输出更多有效位数,因此你能观测到数值末尾的微小偏差。你计算得到的6.007031e-08量级差值,属于浮点数累加过程中正常的舍入误差,不代表数据损坏。- 重新导出为xlsx后偏差消失,是因为
writexl写入文件时遵循Excel的数值存储规则,Excel打开文件时又会自动做显示截断,自然看不到末尾的微小误差。
解决方法
根据你的实际使用场景选对应方案即可:
- 如果是做常规统计分析:这个量级的误差完全可以忽略,不会对分析结果产生实质影响。做数值相等判断时不要直接用
==,改用带容差的判断逻辑即可,比如使用dplyr::near()函数,或判断两数差值的绝对值小于1e-7即视为相等。 - 如果是财务对账等要求数值和Excel显示结果完全一致的场景:导入时先按字符类型读取,再转换为高精度十进制格式计算,示例代码如下:
library(readxl) # 所有列先按字符格式读入,避免浮点数自动转换 target_inputs <- read_excel("A Matrix - Table 5 2019-20.xlsx", sheet = "target_inputs", col_types = "text") target_outputs <- read_excel("A Matrix - Table 5 2019-20.xlsx", sheet = "target_outputs", col_types = "text") # 转换为高精度数值类型计算 library(bit64) inputs_vec <- as.numeric64(as.matrix(target_inputs)) outputs_vec <- as.numeric64(as.matrix(target_outputs)) print(sum(inputs_vec) - sum(outputs_vec))
- 如果不需要极高精度:直接按业务要求的小数位数对数值做四舍五入即可,比如你的数据本身最多保留9位小数,就执行
round(你的数值, 9)后再做求和计算,就能得到和Excel一致的0差值。之前用round()未生效,大概率是设置的保留位数小于数据实际有效小数位,导致累加后仍存在微小误差。
内容的提问来源于stack exchange,提问作者vabm
相关产品推荐
相关产品推荐

