2

可能重复:
为什么这些数字不相等?

我遇到了一个非常奇怪的情况。如果我使用以下代码将向量(序列)存储在文本文件中:

fileConn<-file('test.txt')
sink(fileConn,append=T,split=T)
cat('sequence','\n')
cat(as.character(unlist(seq(0,1,0.1))),'\n')
sink()
close(fileConn)

然后再次加载:

test=readLines('test.txt')

然后,我尝试提取存储在文本文件中的相同向量,并使用 2 种“不同”方法与原始序列进行比较:

sequence1=laply(strsplit(test[2]," ")[[1]],as.numeric)
sequence2=as.numeric(strsplit(test[2]," ")[[1]])

奇怪的是,即使它们看起来和(显然)是相同类型的向量,R 似乎认为它们不是!!!

cbind(seq(0,1,0.1),sequence1,sequence2)

          sequence1 sequence2
 [1,] 0.0       0.0       0.0
 [2,] 0.1       0.1       0.1
 [3,] 0.2       0.2       0.2
 [4,] 0.3       0.3       0.3
 [5,] 0.4       0.4       0.4
 [6,] 0.5       0.5       0.5
 [7,] 0.6       0.6       0.6
 [8,] 0.7       0.7       0.7
 [9,] 0.8       0.8       0.8
[10,] 0.9       0.9       0.9
[11,] 1.0       1.0       1.0

apply(cbind(seq(0,1,0.1),sequence1,sequence2),2,class)
          sequence1 sequence2 
"numeric" "numeric" "numeric"



apply(cbind(seq(0,1,0.1),sequence1,sequence2),2,nchar)
        sequence1 sequence2
 [1,] 1         1         1
 [2,] 3         3         3
 [3,] 3         3         3
 [4,] 3         3         3
 [5,] 3         3         3
 [6,] 3         3         3
 [7,] 3         3         3
 [8,] 3         3         3
 [9,] 3         3         3
[10,] 3         3         3
[11,] 1         1         1

sequence1==seq(0,1,0.1)
 [1]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE

sequence2==seq(0,1,0.1)
 [1]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE

有没有人知道为什么会发生这种情况以及我如何防止它发生?非常感谢!

4

2 回答 2

1

让我们逐步解决您的问题。转储文件后,我可以检查以下内容test.txt

test=readLines('test.txt')
> test
[1] "sequence "                               
[2] "0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 "

如果我们将其与原始序列进行比较:

> seq(0,1,0.1)
 [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

我们看到该文件包含正确的内容。所以,你的处理错误。我们检查两个序列是否与转储的序列匹配:

> all.equal(sequence1, seq(0,1,0.1))
[1] TRUE
> all.equal(sequence2, seq(0,1,0.1))
[1] TRUE

所以实际上他们是正确的。因此,您声称存在问题的说法是错误的。FALSE 可能是由表示浮点数的数值精度引起的,因此all.equal说它们是相同的。

于 2012-11-02T12:13:36.610 回答
1

您想使用 进行比较all.equal(),这允许在比较中进行一些模糊处理。你不能用==它来测试精确的等价性,这不是你不应该也不希望对浮点数据做的事情。

> all.equal(unlist(sequence1), seq(0, 1, 0.1))
[1] TRUE
> all.equal(sequence2, seq(0, 1, 0.1))
[1] TRUE

为了得到你想要的输出,我们需要更加努力:

> sapply(seq_along(sequence1), function(i, x, y) all.equal(x[[i]], y[i]),
+        x = sequence1, y = seq(0, 1, 0.1))
 [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
> sapply(seq_along(sequence2), function(i, x, y) all.equal(x[i], y[i]),
+        x = sequence2, y = seq(0, 1, 0.1))
 [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

请注意最后两个与列表略有不同sequence1

于 2012-11-02T12:16:24.440 回答