我在R中偶然发现了一个奇怪的行为,其中double
值未作为原始值保存到CSV。
可重复的例子:
set.seed(1)
df <- data.frame(ID = 1:10, X = rnorm(10))
write.csv(df, "test.csv", row.names = F)
read.csv("test.csv") == df
ID X
[1,] TRUE FALSE
[2,] TRUE FALSE
[3,] TRUE FALSE
[4,] TRUE FALSE
[5,] TRUE FALSE
[6,] TRUE FALSE
[7,] TRUE FALSE
[8,] TRUE FALSE
[9,] TRUE FALSE
[10,] TRUE TRUE
当然,差异似乎只发生在第15个十进制数字或之后,但它让我不相信CSV文件。
options(digits = 20)
df[1,]
ID X
1 1 -0.62645381074233242
read.csv("test.csv")[1,]
ID X
1 1 -0.62645381074233197
有没有办法绕过这个问题?这是一个已知的错误吗?
答案 0 :(得分:2)
如果您想提高write.csv
功能的精确度,可以使用sprintf
实现这一目标。 &#34; %.20f
&#34;将确保前20个数字相同,这足以让R得出数字相等的结论。
set.seed(1)
df <- data.frame(ID = 1:10, X = rnorm(10))
write.csv(data.frame(df$ID, newX =sprintf("%.20f",df$X)), "test.csv",
row.names = F)
x <- read.csv("test.csv")
x == df
#df.ID newX
[1,] TRUE TRUE
[2,] TRUE TRUE
[3,] TRUE TRUE
[4,] TRUE TRUE
[5,] TRUE TRUE
[6,] TRUE TRUE
[7,] TRUE TRUE
[8,] TRUE TRUE
[9,] TRUE TRUE
[10,] TRUE TRUE
答案 1 :(得分:0)
正如评论中指出的那样,R FAQ解释说问题中的测试不是考虑机器精度的正确方法。
出于存档目的,正确的测试是all.equal
:
all.equal(read.csv("test.csv"), df)
[1] TRUE