我有两个大数据帧,abidentical(a,b)TRUEall.equal(a,b)也是,但是identical(digest(a),digest(b))FALSE。是什么原因造成的?

此外,我尝试通过将摘要应用于成串的行来进行更深入的挖掘。至少在我看来,令人难以置信的是,子帧的摘要值一直到数据帧的最后一行都一致。

这是一系列比较:

> identical(a, b)
[1] TRUE
> all.equal(a, b)
[1] TRUE
> digest(a)
[1] "cac56b06078733b6fb520442e5482684"
> digest(b)
[1] "fdd5ab78ca961982d195f800e3cf60af"
> digest(a[1:nrow(a),])
[1] "e44f906723405756509a6b17b5949d1a"
> digest(b[1:nrow(b),])
[1] "e44f906723405756509a6b17b5949d1a"

我能想到的每种方法都表明这两个对象是相同的,但它们的摘要值却不同。关于数据帧,还有其他可能导致这种差异的地方吗?

有关更多详细信息:对象大约为1000万行x 12列。这是str()的输出:
'data.frame':   10056987 obs. of  12 variables:
 $ V1 : num  1 11 21 31 41 61 71 81 91 101 ...
 $ V2 : num  1 1 1 1 1 1 1 1 1 1 ...
 $ V3 : num  2 3 2 3 4 5 2 4 2 4 ...
 $ V4 : num  1 1 1 1 1 1 1 1 1 1 ...
 $ V5 : num  1.8 2.29 1.94 2.81 3.06 ...
 $ V6 : num  0.0653 0.0476 0.0324 0.034 0.0257 ...
 $ V7 : num  0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 ...
 $ V8 : num  0.00653 0.00476 0.00324 0.0034 0.00257 ...
 $ V9 : num  1.8 2.3 1.94 2.81 3.06 ...
 $ V10: num  0.1957 0.7021 0.0604 0.1866 0.9371 ...
 $ V11: num  1704 1554 1409 1059 1003 ...
 $ V12: num  23309 23309 23309 23309 23309 ...

> print(object.size(a), units = "Mb")
920.7 Mb

更新1:一时兴起,我将它们转换为矩阵。摘要是相同的。
> aM = as.matrix(a)
> bM= as.matrix(b)
> identical(aM,bM)
[1] TRUE
> digest(aM)
[1] "c5147d459ba385ca8f30dcd43760fc90"
> digest(bM)
[1] "c5147d459ba385ca8f30dcd43760fc90"

然后,我尝试将其转换回数据帧,并且摘要值等于(并等于a的先前值)。
> aMF = as.data.frame(aM)
> bMF = as.data.frame(bM)
> digest(aMF)
[1] "cac56b06078733b6fb520442e5482684"
> digest(bMF)
[1] "cac56b06078733b6fb520442e5482684"

因此,b看起来像个坏男孩,并且拥有丰富多彩的过去。 b来自更大的数据帧。我只取了出现在B中的B列,并检查它们是否相等。好吧,他们是平等的,但是有不同的摘要。我转换了列名(从“InformativeColumnName1”到“V1”,等等),只是为了避免可能出现的任何问题-尽管当列名不同时aall.equal往往会指出。

由于我正在使用两个不同的程序,并且无法同时访问identicala,因此对我来说,最简单的方法是使用摘要值来检查计算。但是,如何从数据框中提取列然后将b应用于它,似乎有些奇怪。

解答:
事实证明,令我惊讶的是(令人沮丧,恐怖,尴尬,请您命名),digest()对属性非常宽容。我以为只有identical可以宽恕属性。

这是通过Tommy的建议all.equal发现的。运行identical(d1, d2, attrib.as.set=FALSE)是一个坏主意,不好意思:在Ctrl-C中断行名称之前花了很长时间。这是attributes(a)的输出:
> names(attributes(a))
[1] "names"     "row.names" "class"
> names(attributes(b))
[1] "names"     "class"     "row.names"

他们的顺序不一样!恭喜names(attributes())与我同在。

更新

为了帮助其他人解决此问题,似乎简单地重新排列属性就足以获得相同的哈希值。由于对属性顺序进行修改对我来说是新的,所以这可能会破坏某些东西,但对我而言有效。请注意,如果对象很大,则会浪费一些时间。我不知道执行此操作的更快方法。 (我还希望转向使用矩阵或数据表而不是数据帧,这可能是避免数据帧的另一种诱因。)
tmpA0   = attributes(a)
tmpA1   = tmpA0[sort(names(tmpA0))]
a2      = a
attributes(a2) = tmpA1

tmpB0   = attributes(b)
tmpB1   = tmpB0[sort(names(tmpB0))]
b2      = b
attributes(b2) = tmpB1

digest(a2)  # e04e624692d82353479efbd713ec03f6
digest(b2)  # e04e624692d82353479efbd713ec03f6

identical(b,b2, attrib.as.set = FALSE) # FALSE
identical(b,b2, attrib.as.set = TRUE) # TRUE
identical(a2,b2, attrib.as.set = FALSE) # TRUE

最佳答案

没有实际的data.frames当然是很难知道的,但是其中一个区别可能是属性的顺序identical默认情况下会忽略该设置,但是设置attrib.as.set=FALSE可以更改此设置:

d1 <- structure(1, foo=1, bar=2)
d2 <- structure(1, bar=2, foo=1)

identical(d1, d2) # TRUE
identical(d1, d2, attrib.as.set=FALSE) # FALSE

关于r - R中具有不同摘要的相同数据帧?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7585316/

10-12 16:33
查看更多