将集合操作从 R 的数据帧移植到数据表:如何识别重复行?

Posted

技术标签:

【中文标题】将集合操作从 R 的数据帧移植到数据表:如何识别重复行?【英文标题】:Porting set operations from R's data frames to data tables: How to identify duplicated rows? 【发布时间】:2011-12-10 22:48:32 【问题描述】:

[更新 1:正如 Matthew Dowle 所说,我在 R-Forge 上使用 data.table 版本 1.6.7,而不是 CRAN。在早期版本的 data.table 中您不会看到相同的行为。]

作为背景:我正在移植一些小实用程序函数来对数据框的行或数据框对(即每一行是集合中的一个元素)进行集合操作,例如独特 - 从列表、联合、交集、集合差异等创建集合。这些模仿 Matlab 的 intersect(...,'rows')setdiff(...,'rows') 等,在 R 中似乎没有对应物(R 的集合操作仅限于向量和列表,但不是矩阵行或数据框)。这些小功能的示例如下。如果数据框的这个功能已经存在于某个包或基础 R 中,我愿意接受建议。

我一直在将这些迁移到数据表中,当前方法中的一个必要步骤是查找重复的行。执行duplicated() 时会返回一个错误,指出数据表必须有键。这是一个不幸的障碍 - 除了设置键(这不是通用解决方案并增加计算成本)之外,还有其他方法可以找到重复的对象吗?

这是一个可重现的例子:

library(data.table)
set.seed(0)
x   <- as.data.table(matrix(sample(2, 100, replace = TRUE), ncol = 4))
y   <- as.data.table(matrix(sample(2, 100, replace = TRUE), ncol = 4))

res3    <- dt_intersect(x,y)

产生此错误消息:

Error in duplicated.data.table(z_rbind) : data table must have keys

代码按原样用于数据帧,但我已使用模式dt_operation 命名每个函数。

有没有办法解决这个问题?设置键仅适用于整数,这是我不能为输入数据假设的约束。那么,也许我错过了使用数据表的巧妙方法?


示例集合操作函数,其中集合的元素是数据行:

dt_unique       <- function(x)
    return(unique(x))


dt_union        <- function(x,y)
    z_rbind     <- rbind(x,y)
    z_unique    <- dt_unique(z_rbind)
    return(z_unique)


dt_intersect    <- function(x,y)
    zx          <- dt_unique(x)
    zy          <- dt_unique(y)

    z_rbind     <- rbind(zy,zx)
    ixDupe      <- which(duplicated(z_rbind))
    z           <- z_rbind[ixDupe,]
    return(z)


dt_setdiff      <- function(x,y)
    zx          <- dt_unique(x)
    zy          <- dt_unique(y)

    z_rbind     <- rbind(zy,zx)
    ixRangeX    <- (nrow(zy) + 1):nrow(z_rbind)
    ixNotDupe   <- which(!duplicated(z_rbind))
    ixDiff      <- intersect(ixNotDupe, ixRangeX)
    diffX       <- z_rbind[ixDiff,]
    return(diffX)


注意 1:这些辅助函数的一个预期用途是查找 x 中的键值不在 y 中的键值中的行。这样,我可以在计算x[y]y[x] 时找到可能出现的NA。虽然这种用法允许为 z_rbind 对象设置键,但我不希望自己仅限于这个用例。

注意 2:对于相关的帖子,here is a post 在数据帧上运行 unique,使用更新的 data.table 包运行它的结果非常好。 this is an earlier post 在数据表上运行 unique

【问题讨论】:

【参考方案1】:

duplicated.data.table 需要相同的修复 unique.data.table 得到 [编辑:现在在 v1.7.2 中完成]。请提出另一个错误报告:bug.report(package="data.table")。为了其他人的观看,您已经在使用 R-Forge 的 v1.6.7,而不是 CRAN 上的 1.6.6。

但是,在注释 1 中,有一个“不加入”成语:

x[-x[y,which=TRUE]]

另请参阅 FR#1384(新的 'not' 和 'whichna' 参数?)以使用户更轻松,并链接到更详细的 keys that don't match 线程。


更新。现在在 v1.8.3 中,已经实现了 not-join。

DT[-DT["a",which=TRUE,nomatch=0],...]   # old idiom
DT[!"a",...]                            # same result, now preferred.

【讨论】:

谢谢!好点 - 我忘了提到我已经更新了data.table。另外,bug.report() 对我来说是新的。 马修,你的代码应该是x[-x[y,which=TRUE, nomatch=0]]吗?如果没有 nomatch=0 参数,我会收到此错误:Error in [.default(x[[s]], irows) : only 0's may be mixed with negative subscripts @RYogi。不确定。需要一个例子,也许在一个新问题中。

以上是关于将集合操作从 R 的数据帧移植到数据表:如何识别重复行?的主要内容,如果未能解决你的问题,请参考以下文章

r R:将数据帧写入MySQL数据库,并将数据从数据库查询到R.

R使用XML2将数据从XML提取到数据帧中

如何从 R 中的数据帧创建具有多个参数的函数列表?

使用 rmongodb 和 plyr 将大型 MongoDB 集合传输到 R 中的 data.frame

如何将新列和相应的行特定值添加到火花数据帧?

如何在 python pandas 循环中对数据帧执行操作