以下列数据为例:
dt <- data.table(TICKER=c(rep("ABC",10),"DEF"),
PERIOD=c(rep(as.Date("2010-12-31"),10),as.Date("2011-12-31")),
DATE=as.Date(c("2010-01-05","2010-01-07","2010-01-08","2010-01-09","2010-01-10","2010-01-11","2010-01-13","2010-04-01","2010-04-02","2010-08-03","2011-02-05")),
ID=c(1,2,1,3,1,2,1,1,2,2,1),VALUE=c(1.5,1.3,1.4,1.6,1.4,1.2,1.5,1.7,1.8,1.7,2.3))
setkey(dt,TICKER,PERIOD,ID,DATE)
现在,对于每立方/期的组合,我需要在新的一栏中填写以下内容:
PRIORAVG
: The mean of the latest VALUE of each ID, excluding the current ID, providing it is no more than 180 days old.PREV
: The previous value from the same ID.
结果应该是这样的:
TICKER PERIOD DATE ID VALUE PRIORAVG PREV
[1,] ABC 2010-12-31 2010-01-05 1 1.5 NA NA
[2,] ABC 2010-12-31 2010-01-08 1 1.4 1.30 1.5
[3,] ABC 2010-12-31 2010-01-10 1 1.4 1.45 1.4
[4,] ABC 2010-12-31 2010-01-13 1 1.5 1.40 1.4
[5,] ABC 2010-12-31 2010-04-01 1 1.7 1.40 1.5
[6,] ABC 2010-12-31 2010-01-07 2 1.3 1.50 NA
[7,] ABC 2010-12-31 2010-01-11 2 1.2 1.50 1.3
[8,] ABC 2010-12-31 2010-04-02 2 1.8 1.65 1.2
[9,] ABC 2010-12-31 2010-08-03 2 1.7 1.70 1.8
[10,] ABC 2010-12-31 2010-01-09 3 1.6 1.35 NA
[11,] DEF 2011-12-31 2011-02-05 1 2.3 NA NA
请注意,第9行的 PRIORAVG
等于1.7(等于第5行的 value
,这是过去180天中由另一个 ID
观察到的唯一一次)
我发现了 data.table
软件包, 但我似乎无法完全理解 :\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
dt[,PREV:=dt[J(TICKER,PERIOD,ID,DATE-1),roll=TRUE,mult="last"][,VALUE]]
此功能非常有效, 只要0. 13秒, 就可以用 ~ 250k 列执行此操作; 我的矢量扫描功能结果相同, 但速度要慢约 30,000 倍 。
OK, 所以我已经得到了我的第一个要求。 让我们到第二个, 更复杂的要求。 目前, 对我而言, 禁食的方法是使用几个矢量扫描, 并将函数扔到 < code> plyr code > 函数 < code> adply code > 中, 以获得每行的结果 。
calc <- function(df,ticker,period,id,date) {
df <- df[df$TICKER == ticker & df$PERIOD == period
& df$ID != id & df$DATE < date & df$DATE > date-180, ]
df <- df[order(df$DATE),]
mean(df[!duplicated(df$ID, fromLast = TRUE),"VALUE"])
}
df <- data.frame(dt)
adply(df,1,function(x) calc(df,x$TICKER,x$PERIOD,x$ID,x$DATE))
我为 data.frame
写入了函数,但似乎没有使用 data.table
。对于5000行的子集,这大约需要44秒,但我的数据由 & gt; 100万行组成。我想知道通过使用 :\\\\\\/code > 是否可以提高效率。
dt[J("ABC"),last(VALUE),by=ID][,mean(V1)]
用于选择 ABC 中每个 ID 的最近 VALUE 平均值 。
dt[,PRIORAVG:=dt[J(TICKER,PERIOD),last(VALUE),by=ID][,mean(V1)]]
然而,这没有达到预期的效果, 因为它需要所有中/ 期的所有最后价值的平均值, 而不是当前中/ 期的平均值。 因此它最终导致所有行获得相同的平均值 。 我是不是做错了什么, 或者这是对 < code > 的限制 :\\\ / code >?