我有一个data.table,我想把它分成两部分。我这样做如下:
dt <- data.table(a=c(1,2,3,3),b=c(1,1,2,2))
sdt <- split(dt,dt$b==2)但是如果我想把这样的事情作为下一步
sdt[[1]][,c:=.N,by=a]我收到以下警告信息。
警告消息:在
[.data.table(sdt[1],:=(c,.N),by = a)中:通过获取整个表的副本检测和修复无效的.internal.selfref,以便:=可以通过引用添加这个新列。在较早的时候,这个data.table已经被R复制了。避免键<-,名称<-和attr<-,这在R中(奇怪的是)可以复制整个data.table。使用set*语法来避免复制: setkey()、setname()和setattr()。此外,list( DT1,DT2)将复制整个DT1和DT2 (R的list()复制命名对象),如果需要(要实现)则使用reflist()。如果此消息不起作用,请向datatable-help报告,以便解决根本原因。
只是想知道是否有更好的方法来分割表,这样它才能更有效(并且不会得到这个消息)?
发布于 2013-02-20 11:25:09
这在1.8.7版中有效(在1.8.6版中也适用):
> sdt = lapply(split(1:nrow(dt), dt$b==2), function(x)dt[x])
> sdt
$`FALSE`
a b
1: 1 1
2: 2 1
$`TRUE`
a b
1: 3 2
2: 3 2
> sdt[[1]][,c:=.N,by=a] # now no warning
> sdt
$`FALSE`
a b c
1: 1 1 1
2: 2 1 1
$`TRUE`
a b
1: 3 2
2: 3 2但是,正如@mnel所说,这是低效的。如果可能的话,请避免分裂。
发布于 2015-07-06 12:52:12
我正在寻找一种在data.table中实现分裂的方法,我偶然发现了一个老问题。
有时候,拆分是您想要做的,而data.table "by“方法并不方便。
实际上,您只需使用data.table指令就可以轻松地手工完成拆分,并且非常有效:
SplitDataTable <- function(dt,attr) {
boundaries=c(0,which(head(dt[[attr]],-1)!=tail(dt[[attr]],-1)),nrow(dt))
return(
mapply(
function(start,end) {dt[start:end,]},
head(boundaries,-1)+1,
tail(boundaries,-1),
SIMPLIFY=F))
}发布于 2019-08-30 13:13:24
正如上面提到的(@jangorecki),包data.table已经有了自己的拆分功能。在这种简化的情况下,我们可以使用:
> dt <- data.table(a = c(1, 2, 3, 3), b = c(1, 1, 2, 2))
> split(dt, by = "b")
$`1`
a b
1: 1 1
2: 2 1
$`2`
a b
1: 3 2
2: 3 2对于更困难/具体的情况,我建议在data.table中使用by reference函数:=或set创建一个新变量,然后调用函数split。如果您关心性能,请确保始终保持在data.table环境(例如,dt[, SplitCriteria := (...)] )中,而不是外部计算拆分变量。
https://stackoverflow.com/questions/14977997
复制相似问题