使用哈希来确定2个数据帧是否相同(第01部分)

lok*_*art 5 hash r

我一直在使用创建数据WHO ATC/DDD指数前几个月,我要确保,如果数据库联机今天保持不变,所以我重新下载,并尝试使用该digest软件包中的R做比较.

这两个数据集(格式为txt)可以在这里下载.(我知道您可能认为文件不安全并且可能有病毒,但我不知道如何生成虚拟数据集来复制我现在的问题,所以我最后上传了数据集)

我写了一个小脚本如下:

library(digest)

ddd.old <- read.table("ddd.table.old.txt",header=TRUE,stringsAsFactors=FALSE)
ddd.new <- read.table("ddd.table.new.txt",header=TRUE,stringsAsFactors=FALSE)


ddd.old[,"ddd"] <- as.character(ddd.old[,"ddd"])
ddd.new[,"ddd"] <- as.character(ddd.new[,"ddd"])

ddd.old <- data.frame(ddd.old, hash = apply(ddd.old, 1, digest),stringsAsFactors=FALSE)
ddd.new <- data.frame(ddd.new, hash = apply(ddd.new, 1, digest),stringsAsFactors=FALSE)

ddd.old <- ddd.old[order(ddd.old[,"hash"]),]
ddd.new <- ddd.new[order(ddd.new[,"hash"]),]
Run Code Online (Sandbox Code Playgroud)

当我进行检查时会发生一些非常有趣的事情:

> table(ddd.old[,"hash"]%in%ddd.new[,"hash"]) #line01

TRUE 
 506 
> table(ddd.new[,"hash"]%in%ddd.old[,"hash"]) #line02

TRUE 
 506 
> digest(ddd.old[,"hash"])==digest(ddd.new[,"hash"]) #line03
[1] TRUE
> digest(ddd.old)==digest(ddd.new) #line04
[1] FALSE
Run Code Online (Sandbox Code Playgroud)
  • line01line02显示ddd.old可以找到每一行,ddd.new反之亦然.
  • line03表明hash两个数据帧的列都相同
  • line04 表明两个数据帧是不同的

发生什么事?两个数据帧具有相同的行(来自line01line02),相同的顺序(来自line03),但是不同?(来自line04)

或者我有任何误解digest吗?谢谢.

Ric*_*ton 4

像以前一样读入数据。

ddd.old <- read.table("ddd.table.old.txt",header=TRUE,stringsAsFactors=FALSE)
ddd.new <- read.table("ddd.table.new.txt",header=TRUE,stringsAsFactors=FALSE)
ddd.old[,"ddd"] <- as.character(ddd.old[,"ddd"])
ddd.new[,"ddd"] <- as.character(ddd.new[,"ddd"])
Run Code Online (Sandbox Code Playgroud)

就像 Marek 所说,首先检查与 的差异all.equal

all.equal(ddd.old, ddd.new)
[1] "Component 6: 4 string mismatches" 
[2] "Component 8: 24 string mismatches"
Run Code Online (Sandbox Code Playgroud)

所以我们只需要看看第 6 列和第 8 列。

different.old <- ddd.old[, c(6, 8)]   
different.new <- ddd.new[, c(6, 8)]
Run Code Online (Sandbox Code Playgroud)

对这些列进行哈希处理。

hash.old <- apply(different.old, 1, digest)
hash.new <- apply(different.new, 1, digest)
Run Code Online (Sandbox Code Playgroud)

并找到不匹配的行。

different_rows <- which(hash.old != hash.new)  #which is optional
Run Code Online (Sandbox Code Playgroud)

最后,合并数据集。

cbind(different.old[different_rows, ], different.new[different_rows, ])
Run Code Online (Sandbox Code Playgroud)