![](/img/trans.png)
[英]Match values in two different data frames, that are not identical, with matching pattern in R
[英]Identical data frames with different digests in R?
我有兩個大數據幀, a
和b
的identical(a,b)
為TRUE
, all.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
。 我只拿了出現在a
的B
列並檢查它們是否相等。 嗯,他們是平等的,但有不同的摘要。 我轉換的列名(從“InformativeColumnName1”到“V1”,等等),只是為了避免可能出現的任何問題-盡管all.equal
和identical
傾向於指出,當列名稱不同。
由於我正在處理兩個不同的程序,並且沒有同時訪問a
和b
,因此最簡單的方法是使用摘要值來檢查計算。 但是,如何從數據框中提取列然后對其應用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.