[更新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]
时可能出现的位置。虽然这种用法允许设置z_rbind
对象的密钥,但我不想仅限于此用例。
注意2:对于相关帖子,here is a post关于在数据框架上运行unique
,使用更新的data.table
软件包运行它的效果非常好。
并this is an earlier post在数据表上运行unique
。
答案 0 :(得分:6)
duplicated.data.table
需要相同的修复unique.data.table
[编辑:现在在v1.7.2中完成]。请提出另一个错误报告:bug.report(package="data.table")
。为了让其他人观看,你已经使用了R-Forge的v1.6.7,而不是CRAN的1.6.6。
但是,在注1中,有一个'not join'成语:
x[-x[y,which=TRUE]]
另请参阅FR#1384(新的'not'和'whichna'参数?),以便用户更轻松,并链接到更详细的keys that don't match主题。
<强>更新即可。现在在v1.8.3中,已经实现了非连接。
DT[-DT["a",which=TRUE,nomatch=0],...] # old idiom
DT[!"a",...] # same result, now preferred.