R按组进行最后一次观察n次

时间:2018-01-22 23:44:05

标签: r data.table locf

这个让我疯了。我有一个大的data.table与月度股票数据。每年六月我都会根据会计变量将每只股票分配给10个投资组合中的一个。我希望将指定的投资组合变量结转到下一个11个月,直到明年6月每只股票被分配到新的投资组合1到10。 na.locf基本上是我正在寻找的,但我遇到了两个问题:

  1. 有些股票明年缺乏足够的会计数据,所以不应该在那一年将它们分配给投资组合(即投资组合变量应保持NA)。但当然na.locf会继续推进投资组合编号,直到有新编号。
  2. 某些股票可能会在以下情况下被除名3个月,所以他们没有另外11个月的数据。
  3. 这就是为什么我要寻找一个代码,将最后一次观察结果推迟到明年6月(当有新的投资组合编号时)最多11次。

    这是na.locf解决方案,现在有2个问题(PERMNO是股票标识符):

    COMPUSTAT_CRSP_IBES1[,
                         Portfolio_Monthly := na.locf(Portfolio_Monthly, 
                                                      na.rm = FALSE),
                         by = PERMNO]
    

    我尝试使用rep,但这根本不起作用:

    COMPUSTAT_CRSP_IBES1[,
                         Portfolio_Monthly := if_else(!is.na(Portfolio_Monthly), 
                                                      rep(Portfolio_Monthly, 11), 
                                                      NA), 
                         by = PERMNO]
    

    感谢任何提示!

1 个答案:

答案 0 :(得分:1)

您可以创建和/或使用您的会计年度(6月 - 5月)作为by解决方案中的na.locf组标准之一

#show data before calculations
data.frame(dat)

#demo FY calculation
dat[, FY := year(MONTH) + as.numeric(month(MONTH) >= 6)]

#actual code
dat[, Portfolio_Monthly := zoo::na.locf(Portfolio_Monthly, na.rm=FALSE),
    by=list(PERMNO, year(MONTH) + as.numeric(month(MONTH) >= 6))]

#show results
data.frame(dat)

样本数据:

library(data.table)
set.seed(0L)
dat <- data.table(PERMNO=rep(LETTERS[1:12], each=20), 
    MONTH=rep(seq(as.Date("2000-01-01"), by="1 month", length.out=20), 12),
    Portfolio_Monthly=NA_real_)
for (i in sample(1:dat[,.N], 5)) {
    set(dat, i, 3L, rnorm(1))   
}
setorder(dat, PERMNO, MONTH)