R `j`dons';t为每组计算相同数量的列
我正在尝试使用data.table,其中我的R `j`dons';t为每组计算相同数量的列,r,data.table,R,Data.table,我正在尝试使用data.table,其中我的j函数可以并且将在每次调用中返回不同数量的列。我希望它的行为类似于rbind.fill,因为它用NA填充任何缺少的列 fetch <- function(by) { if(by == 1) data.table(A=c("a"), B=c("b")) else data.table(B=c("b")) } data <- data.table(id=c(1,2)) result <- d
j
函数可以并且将在每次调用中返回不同数量的列。我希望它的行为类似于rbind.fill
,因为它用NA
填充任何缺少的列
fetch <- function(by) {
if(by == 1)
data.table(A=c("a"), B=c("b"))
else
data.table(B=c("b"))
}
data <- data.table(id=c(1,2))
result <- data[, fetch(.BY), by=id]
我可以用plyr
完成这项工作,如下所示,但在我的实际用例中plyr
内存不足。每次调用fetch
都会很快发生,但是当plyr
尝试将所有数据合并回一起时,内存崩溃就会发生。我正在尝试查看data.table
是否可以为我解决此问题
result <- ddply(data, "id", fetch)
结果尝试
@尼卡伦:从评论中我不确定你是否理解我的建议。(我用手机发帖,这限制了我的剪贴功能,我怀疑我妻子是在告诉我不要再发短信给S0,否则她会和我离婚。)我的意思是:
fetch <- function(by) {
if(by == 1)
data.table(A=c("a"), B=c("b"))
else
data.table(A=NA, B=c("b"))
}
data <- data.table(id=c(1,2))
result <- data[, fetch(.BY), by=id]
fetchDWin的方法很好。或者您可以返回一个列表
列,其中每个单元格本身就是一个向量。这通常是处理可变长度向量的更好方法
DT = data.table(A=rep(1:3,1:3),B=1:6)
DT
A B
1: 1 1
2: 2 2
3: 2 3
4: 3 4
5: 3 5
6: 3 6
ans = DT[, list(list(B)), by=A]
ans
A V1
1: 1 1
2: 2 2,3 # V1 is a list column. These aren't strings, the
3: 3 4,5,6 # vectors just display with commas
ans$V1[3]
[[1]]
[1] 4 5 6
ans$V1[[3]]
[1] 4 5 6
ans[,sapply(V1,length)]
[1] 1 2 3
因此,在您的示例中,您可以使用以下方法:
library(plyr)
rbind.fill(data[, list(list(fetch(.BY))), by = id]$V1)
# A B
#1 a b
#2 <NA> b
库(plyr)
rbind.fill(数据[,列表(列表(fetch(.BY))),BY=id]$V1)
#A B
#1 a b
#2 b
或者,只需使返回的列表保持一致:
allcols = c("A","B")
fetch <- function(by) {
if(by == 1)
list(A=c("a"), B=c("b"))[allcols]
else
list(B=c("b"))[allcols]
}
allcols=c(“A”、“B”)
fetch这里有两种方法。第一种方法大致遵循您的策略:
data[,list(A=if(.BY==1) 'a' else NA_character_,B='b'), by=id]
第二步分两步进行:
DT <- copy(data)[,`:=`(A=NA_character_,B='b')][id==1,A:='a']
DT我想这不是我想要的。我试图对一个数据表应用一个函数,这将导致另一个数据表。那么我一定问错了问题。:)我不想手动创建这样的数据表。这只是我想做的一个例子。对不起,我不清楚。如果我描述一下我的真实用例,也许会有所帮助。上面的My fetch()函数发出一个web服务调用,该调用提取一些关于事件的JSON数据;音乐会、运动会等。一项活动可以有一名或多名表演者。我获取每个事件的JSON数据,并将其平铺到数据表中。第一个事件可能有3列;事件id、执行者1、执行者2。第二个事件可能有两列;事件id,执行者1。所以我需要将所有这些事件合并到一个数据帧中。由于第二个事件没有第二个执行者,它在performer_2列中应该有NA。@NickAllen如我的回答所示,将performer粘贴在列表中如何?或者保持长格式而不是宽格式。或者,如果你事先知道将返回的列数最多,那么使用类似于我答案末尾的内容将其固定。是的,这些都是好主意。我认为,将这些数据“广泛”地保存在训练中是不可行的。但保持“长时间”可能是可行的。Thanksrbind.fill(.data.table)应该是默认值behavior@eddi不幸的是,我不知道该如何实施<代码>数据。表的速度来自于在第一组结果已知后进行猜测。此时(猜测的)行数和列数将提前分配。然后在分组开始时直接填充。rbind.fill
功能需要预先获得所有结果,才能知道返回的所有列。@eddi如果后续的j
返回以前未看到的列名,我想它可以通过引用(为以前的组填充NA)动态地将该列添加到结果中。也许它是可行的。field-只是要补充一点,对于较新版本的data.table
,现在可以使用rbindlist(data[,,(.(fetch(.BY))),BY=id]$V1,use.names=TRUE,fill=TRUE)
我也有同样的问题。我正在按组计算data.table中的函数,myDT[,fun(.SD),ID]为每个组输出不同大小的向量。如何为向量的每个元素生成新行,而不是列表?。我试过使用t()、list(list())、as.data.table()、cbind()和许多其他组合。@skan您的问题可能值得在一个新问题中作为一个可复制的示例发布。我认为我们不能仅根据您在评论中的描述来调试它(因为我觉得它应该已经可以工作了)
allcols = c("A","B")
fetch <- function(by) {
if(by == 1)
list(A=c("a"), B=c("b"))[allcols]
else
list(B=c("b"))[allcols]
}
data[,list(A=if(.BY==1) 'a' else NA_character_,B='b'), by=id]
DT <- copy(data)[,`:=`(A=NA_character_,B='b')][id==1,A:='a']