簡體   English   中英

R中具有不同摘要的相同數據幀?

[英]Identical data frames with different digests in R?

我有兩個大數據幀, 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"

我能想到的每個方法都表明這兩個對象是相同的,但它們的摘要值是不同的。 數據框還有其他可以產生這種差異的東西嗎?


有關詳細信息:對象大約是10M行x12列。 這是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 我只拿了出現在aB列並檢查它們是否相等。 嗯,他們是平等的,但有不同的摘要。 我轉換的列名(從“InformativeColumnName1”到“V1”,等等),只是為了避免可能出現的任何問題-盡管all.equalidentical傾向於指出,當列名稱不同。

由於我正在處理兩個不同的程序,並且沒有同時訪問ab ,因此最簡單的方法是使用摘要值來檢查計算。 但是,如何從數據框中提取列然后對其應用digest()似乎有些奇怪。


答案:事實證明,令我驚訝的是(沮喪,恐怖,尷尬,你的名字), identical對屬性非常寬容。 我假設只有all.equal對屬性寬容。

這是通過Tommy的建議identical(d1, d2, attrib.as.set=FALSE)發現的identical(d1, d2, attrib.as.set=FALSE) 運行attributes(a)是一個糟糕的壞主意:在Ctrl-C可以中斷之前,行名稱的泛濫需要一段時間。 這是names(attributes())的輸出names(attributes())

> names(attributes(a))
[1] "names"     "row.names" "class"    
> names(attributes(b))
[1] "names"     "class"     "row.names"

他們的訂單不同! 感謝digest()與我直接相處。

UPDATE

為了幫助其他人解決這個問題,似乎只需重新排列屬性即可獲得相同的哈希值。 由於修改屬性訂單對我來說是新的,這可能會破壞某些東西,但它適用於我的情況。 請注意,如果對象很大,則需要花費一些時間。 我不知道更快的方法。 (我也希望轉向使用矩陣或數據表而不是數據幀,這可能是避免數據幀的另一個動機。)

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函數serialize()來獲取我們提供給哈希生成函數(md5,sha1,...)的內容。

所以我強烈懷疑可能有類似屬性的東西不同。 除非你能夠構建一個不依賴於你的1e7 x 12數據集的可重現的東西,否則我們無能為力。

此外, digest()函數可以輸出中間結果和(截至最近的0.5.1版本)甚至raw向量。 這可能有所幫助。 最后,您可以隨時聯系我們(作為軟件包維護人員/作者)離線,這恰好是R land中的推薦方式,StackOverflow的普及程度無法承受。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM