簡體   English   中英

比較 R 中的 2 個數據幀的相等性

[英]Compare 2 dataframes for equality in R

我有 2 個具有 2 個相同列的數據框。 我想檢查數據集是否相同。 原始數據集有大約 700K 條記錄,但我正試圖找出一種使用虛擬數據集的方法

我嘗試使用比較、相同、全部、all_equal 等。它們都沒有返回 True。

虛擬數據集是 -

a <- data.frame(x = 1:10, b = 20:11)
c <- data.frame(x = 10:1, b = 11:20)

all(a==c)
[1] FALSE

compare(a,c)
FALSE [FALSE, FALSE]

identical(a,c)
[1] FALSE

 all.equal(a,c)
[1] "Component “x”: Mean relative difference: 0.9090909" "Component “b”: Mean relative difference: 0.3225806"

除了記錄的順序外,數據集完全相同。 如果這些功能只在數據集是彼此的鏡像時才起作用,那么我必須嘗試其他方法。 如果是這種情況,有人可以幫助我如何為這 2 個數據集獲得 True(無序)

dplyrsetdiff適用於數據框,我建議

library(dplyr)
nrow(setdiff(a, c)) == 0 & nrow(setdiff(c, a)) == 0
# [1] TRUE

請注意,這不會考慮重復行的數量 (即,如果a有一行的多個副本,而c只有該行的一個副本,它仍將返回TRUE )。 不確定您希望如何處理重復的行...

如果您確實關心具有相同數量的重復項,那么我建議兩種可能性:(a)添加一個 ID 列來區分重復項並使用上述方法,或(b)排序,重置行名稱(煩人),並使用identical .

(a)添加 ID 列

library(dplyr)
a_id = group_by_all(a) %>% mutate(id = row_number())
c_id = group_by_all(c) %>% mutate(id = row_number())
nrow(setdiff(a_id, c_id)) == 0 & nrow(setdiff(c_id, a_id)) == 0
# [1] TRUE

(b)排序

a_sort = a[do.call(order, a), ]
row.names(a_sort) = NULL
c_sort = c[do.call(order, c), ]
row.names(c_sort) = NULL
identical(a_sort, c_sort)
# [1] TRUE

也許您需要在比較之前對列進行排序的函數。 但是在大型數據幀上會很慢。

unordered_equal <- function(X, Y, exact = FALSE){
  X[] <- lapply(X, sort)
  Y[] <- lapply(Y, sort)
  if(exact) identical(X, Y) else all.equal(X, Y)
}

unordered_equal(a, c)
#[1] TRUE
unordered_equal(a, c, TRUE)
#[1] TRUE

a$x <- a$x + .Machine$double.eps
unordered_equal(a, c)
#[1] TRUE
unordered_equal(a, c, TRUE)
#[1] FALSE

基本上你想要的可能是比較有序的基礎矩陣。

all.equal(matrix(unlist(a[order(a[1]), ]), dim(a)),
          matrix(unlist(c[order(c[1]), ]), dim(c)))
# [1] TRUE
identical(matrix(unlist(a[order(a[1]), ]), dim(a)),
          matrix(unlist(c[order(c[1]), ]), dim(c)))
# [1] TRUE

為了更方便,您可以將其包裝到一個函數中:

om <- function(d) matrix(unlist(d[order(d[1]), ]), dim(d))

all.equal(om(a), om(c))
# [1] TRUE

您可以使用名為 waldo 的新包

library(waldo)
a <- data.frame(x = 1:10, b = 20:11)
c <- data.frame(x = 10:1, b = 11:20)

compare(a,c)

你會得到:

`old$x`: 1 2 3 4 5 6 7 8 9 10 and 9 more...
`new$x`:                   10           ...

`old$b`: 20 19 18 17 16 15 14 13 12 11 and 9 more...
`new$b`: 

暫無
暫無

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

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