我正在使用setDT()将其他列添加到data.table但
setDT(mydata)[, paste0('F2_E',2:30) := lapply(.SD, function(x) log(value/x)), .SDcols = 32:60][]
运行此脚本时未添加:
library(data.table)
library(zoo)
date = seq(as.Date("2016-01-01"),as.Date("2016-05-10"),"day")
value =seq(1,131,1)
mydata = data.frame (date, value)
mydata
setDT(mydata)[, paste0('F1',2:30) := lapply(2:30, function(x) rollmeanr(value, x, fill = rep(NA,x-1)) ),][]
setDT(mydata)[, paste0('F2',2:30) := lapply(2:30, function(x) rollapply(value,x,FUN="median",align="right",fill=NA))][]
setDT(mydata)[, paste0('F1_E',2:30) := lapply(.SD, function(x) log(value/x) ), .SDcols = 3:31][]
setDT(mydata)[, paste0('F2_E',2:30) := lapply(.SD, function(x) log(value/x)), .SDcols = 32:60][]
rbind(colnames(mydata))
rbind(colnames(mydata))
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26] [,27]
[1,] "date" "value" "F12" "F13" "F14" "F15" "F16" "F17" "F18" "F19" "F110" "F111" "F112" "F113" "F114" "F115" "F116" "F117" "F118" "F119" "F120" "F121" "F122" "F123" "F124" "F125" "F126"
[,28] [,29] [,30] [,31] [,32] [,33] [,34] [,35] [,36] [,37] [,38] [,39] [,40] [,41] [,42] [,43] [,44] [,45] [,46] [,47] [,48] [,49] [,50] [,51] [,52] [,53] [,54]
[1,] "F127" "F128" "F129" "F130" "F22" "F23" "F24" "F25" "F26" "F27" "F28" "F29" "F210" "F211" "F212" "F213" "F214" "F215" "F216" "F217" "F218" "F219" "F220" "F221" "F222" "F223" "F224"
[,55] [,56] [,57] [,58] [,59] [,60] [,61] [,62] [,63] [,64] [,65] [,66] [,67] [,68] [,69] [,70] [,71] [,72] [,73] [,74] [,75] [,76] [,77]
[1,] "F225" "F226" "F227" "F228" "F229" "F230" "F1_E2" "F1_E3" "F1_E4" "F1_E5" "F1_E6" "F1_E7" "F1_E8" "F1_E9" "F1_E10" "F1_E11" "F1_E12" "F1_E13" "F1_E14" "F1_E15" "F1_E16" "F1_E17" "F1_E18"
[,78] [,79] [,80] [,81] [,82] [,83] [,84] [,85] [,86] [,87] [,88] [,89]
[1,] "F1_E19" "F1_E20" "F1_E21" "F1_E22" "F1_E23" "F1_E24" "F1_E25" "F1_E26" "F1_E27" "F1_E28" "F1_E29" "F1_E30"
你可以看到没有F2_E2,F2_E3等......列。
为什么不添加这些列?
答案 0 :(得分:2)
简短回答:
使用setDT(mydata)
一次,然后单独使用。然后完成所有作业陈述。
此外,如果您要添加大量列,请使用函数alloc.col()
预先分配更多插槽,直到下一个版本(v1.9.8)。即,
setDT(mydata)
truelength(mydata) # [1] 100
alloc.col(mydata, 1000L)
truelength(mydata) # [1] 1000
在current development version, v1.9.7中,默认情况下我们将过度分配增加到了1024。所以这应该很少发生。
快速而细致的解释:
这是因为data.table 在创建过程中过度分配列指针,而默认的 over-allocation 长度为100列。您可以使用truelength()
进行检查。请参阅?truelength
。
require(data.table)
mydata = data.frame (x=1, y=2)
setDT(mydata) ## convert to data.table by reference
length(mydata) ## equals the columns assigned
# [1] 2
truelength(mydata) ## total number of column slots allocated
# [1] 100
让我们按照您的方式添加30多列。
setDT(mydata)[, paste0("z", 1:30) := 1L]
length(mydata) ## [1] 32
truelength(mydata) ## [1] 100
另外30岁。
setDT(mydata)[, paste0("z", 31:60) := 1L]
length(mydata) ## [1] 62
truelength(mydata) ## [1] 100
另外30岁。
setDT(mydata)[, paste0("z", 61:90) := 1L]
length(mydata) ## [1] 92
truelength(mydata) ## [1] 100
现在,下次我们执行此操作时,我们还要添加30个列,但我们只有 8 更多的广告位。因此,我们需要创建具有更多过度分配的插槽的另一个对象,将当前位于mydata
的所有列分配给新对象,最后将其分配回mydata
。这是内部和自动处理的,因此用户不必跟踪。所以下次我们这样做:
setDT(mydata)[, paste0("z", 91:120) := 1L]
函数[.data.table
意识到它需要再次过度分配,并且这样做,并且新列被添加到新对象中。问题是将此新对象的结果分配回mydata
的父框架中的[.data.table
。这是通过assign()
语句完成的,该语句只接受变量名作为字符输入,setDT(mydata)
不是。{1}}。因此重新分配步骤失败,因此过度分配不能反映回原始对象。如果您已完成mydata[, paste0(..) := ...]
,则输入对象mydata
是名称,可用于将过度分配的结果分配回原始对象,并且这就是@thelatemail的建议可行的原因。
如果这太高级,只需升级到devel版本,这一切都会消失,并且不太可能发生(除非你想要在数据中包含超过1024列) 。表)。
我已提交#1731提醒我们回过头来看看是否还有其他方法可以解决此问题。
答案 1 :(得分:0)
我遇到了与你相同的问题。我们可以尝试ping data.table
专家来理解这个问题。 @latemail获取所需的输出,因此它适用于某人。
与此同时,由于您在第三次和第四次调用上运行相同的操作,我们可以将它们合并为一个以获得所需的输出:
mydata[, paste0(rep(c('F1_E', 'F2_E'),each=29), rep(2:30, 2)) := lapply(.SD, function(x) log(value/x)), .SDcols = 3:60][]
dim(mydata)
[1] 131 118
修改强>
删除方括号,它将起作用。我会抓住我的头一段时间,直到找出原因。