fwrite与fread后数据合并失败问题求助
问题分析与解决:fwrite/fread后merge失败的原因及修复
核心原因:浮点数精度的隐形差异
虽然all.equal(region, region2)返回TRUE,但这是因为all.equal默认容忍微小的数值差异(默认tolerance = 1e-8)。而data.table的merge是精确匹配,当CSV写入/读取后,x和y列的浮点数在二进制层面出现了肉眼不可见的精度损失,导致无法匹配。
你可以通过以下代码验证这个差异:
# 查看x列第一个值的高精度输出 sprintf("%.20f", region$x[1]) sprintf("%.20f", region2$x[1]) # identical会严格检查二进制一致性,返回FALSE identical(region$x, region2$x)
三种修复方案
方案1:提升fwrite的输出精度
在写入CSV时,通过digits参数保留更多小数位,减少精度损失:
# 写入时设置digits=15(接近双精度浮点数的最大有效位数) fwrite(region, "region.csv", digits = 15) region2 <- fread("region.csv", stringsAsFactors = TRUE) # 重新合并 merged_region2 <- merge(TEST, region2, all.x = TRUE) |> drop_na(region)
方案2:读取后对齐浮点数精度
对TEST和region2的x/y列做舍入处理,统一精度:
region2 <- fread("region.csv", stringsAsFactors = TRUE) # 舍入到5位小数(根据你的数据精度调整) region2[, c("x", "y") := lapply(.SD, round, digits = 5), .SDcols = c("x", "y")] TEST[, c("x", "y") := lapply(.SD, round, digits = 5), .SDcols = c("x", "y")] merged_region2 <- merge(TEST, region2, all.x = TRUE) |> drop_na(region)
方案3:使用RDS格式保存(推荐)
CSV是文本格式,天生会损失数值精度;用RDS格式可以完整保留数据的结构和二进制精度:
# 保存为RDS saveRDS(region, "region.rds") # 读取RDS region2 <- readRDS("region.rds") # 合并完全正常 merged_region2 <- merge(TEST, region2, all.x = TRUE) |> drop_na(region)
内容的提问来源于stack exchange,提问作者ChuDingjin
相关产品推荐
相关产品推荐

