在R中为数据框的每一行创建哈希值。

5

我正在探索如何更有效地比较两个R数据框,并且想到了哈希。

我的计划是为具有相同列的两个数据框中的每一行数据创建哈希,使用digest包中的digest函数,并且我认为对于任何两个相同的数据行,哈希值应该是相同的。

我尝试使用以下代码为每一行数据提供唯一的哈希值:

for (loop.ssi in (1:nrow(ssi.10q3.v1)))
    {ssi.10q3.v1[loop.ssi,"hash"] <- digest(as.character(ssi.10q3.v1[loop.ssi,]))
     print(paste(loop.ssi,nrow(ssi.10q3.v1),sep="/"))
     flush.console()
    }

但这非常缓慢。

我比较数据框的方法正确吗?如果是,有没有建议可以加快上面的代码?谢谢。

更新

我已经按照下面的方式更新了代码:

ssi.10q3.v1[,"uid"] <- 1:nrow(ssi.10q3.v1)   

ssi.10q3.v1.hash <- ddply(ssi.10q3.v1,
                          c("uid"),
                          function(df)
                             {df[,"uid"]<- NULL
                              hash <- digest(as.character(df))
                              data.frame(hash=hash)
                             },
                          .progress="text")     

我为了“唯一”目的自动生成了一个uid列。


什么使这一行独特?也许最好/更快的方法是比较每个字段。有没有办法将哈希添加到数据中,这样您就不必每次都生成哈希?您可以将所有字段连接在一起作为一个字段,然后进行测试。也许会更快?FYI-我对R一无所知。 - Shiv Kumar
我建议查看 plyr::join(以及开发版本中的 match_df)来实现比较和匹配数据框的策略。另请参阅 plyr::join.dfplyr::id - hadley
2个回答

6
如果我正确理解您的意思,digest将直接与apply一起使用:
library(digest)
ssi.10q3.v1.hash <- data.frame(uid = 1:nrow(ssi.10q3.v1), hash = apply(ssi.10q3.v1, 1, digest))

通过将 uid = nrow(ssi.10q3.v1) 更改为 uid = 1:nrow(ssi.10q3.v1),这将变得完美,谢谢! - lokheart

1

我知道这个答案与问题的标题不符,但如果你只想看到行有何不同,你可以直接这样做:

rowSums(df2 == df1) == ncol(df1)

假设两个数据框具有相同的维度,那么对于每一行不相同的情况,它将评估为FALSE。如果您还需要测试行名称,可以单独处理并与内容测试结合使用,列名称(和属性以及对列类型的严格测试)也是如此。
 rowSums(df2 == df1) == ncol(df1) & rownames(df2) == rownames(df1)

我猜你认为数据框中全部都是数字,但实际上并不是这样,所以我认为使用rowSums是不可能的。 - lokheart
1
rowSums接收的是一个逻辑矩阵作为输入,而不是数据框——这是==比较的结果——依赖于逻辑值的数值转换来进行求和有点有趣,但并不是什么大问题。 - mdsumner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接