Ite*_*tor 6 r dataframe set-operations data.table
[更新1:正如Matthew Dowle所说,我data.table在R-Forge上使用的是1.6.7版本,而不是CRAN.您不会在早期版本中看到相同的行为data.table.]
作为背景:我正在移植一些小实用程序函数来对数据帧的行或数据帧对进行集合操作(即每行是一个集合中的元素),例如唯一 - 从列表中创建集合,union,交叉点,设置差,等,这些模拟物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)
Run Code Online (Sandbox Code Playgroud)
产生此错误消息:
Error in duplicated.data.table(z_rbind) : data table must have keys
Run Code Online (Sandbox Code Playgroud)
代码按原样用于数据帧,尽管我已经用模式命名了每个函数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)
}
Run Code Online (Sandbox Code Playgroud)
注1:这些辅助函数的一个预期用途是查找x中的键值不在y中的键值中的行.这样一来,我可以找到哪里来港可以在计算时出现x[y]或y[x].虽然这种用法允许设置z_rbind对象的键,但我不想仅限于这个用例.
注2:对于相关帖子,这里有一篇关于unique在数据框架上运行的帖子,使用更新的data.table软件包运行它有很好的结果.而这是一个早期的岗位上运行unique的数据表.
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]]
Run Code Online (Sandbox Code Playgroud)
另请参阅FR#1384(新的'not'和'whichna'参数?)以使用户更容易,并且链接到与线程不匹配的键,这些更详细.
更新.现在在v1.8.3中,已经实现了not-join.
DT[-DT["a",which=TRUE,nomatch=0],...] # old idiom
DT[!"a",...] # same result, now preferred.
Run Code Online (Sandbox Code Playgroud)