将集合操作从 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.