[更新 1:正如 Matthew Dowle 所指出的,我data.table
在 R-Forge 上使用的是 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
尽管我用 pattern 命名了每个函数,但该代码对数据帧按原样工作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]
或时找到 NA 可能出现的位置y[x]
。尽管这种用法允许为z_rbind
对象设置键,但我不想将自己限制在这个用例上。
注意 2:对于相关的帖子,这里有一篇关于在数据帧上运行的帖子,使用更新的包unique
运行它的结果非常好。data.table
这是关于在数据表上运行的早期帖子。unique