这个老问题至今没有答案。
OP 已要求将长格式改为宽格式,其中返回值应排列在 12 列中,代表每个开始月后的 12 个月。
这可以使用data.table 包中的dcast() 和rowid() 函数来完成。
library(data.table)
dcast(setDT(DT), name + startmonth + d1 + d2 + d3 ~ sprintf("M_%02i", rowid(name, startmonth)),
value.var = "return")
name startmonth d1 d2 d3 M_01 M_02 M_03 M_04 M_05 M_06 M_07 M_08 M_09 M_10 M_11 M_12
1: 0001 2000-01-01 A B C -56.0 -23.0 155.9 7.1 12.9 171.5 46.1 -126.5 -68.7 -44.6 122.4 36.0
2: 0001 2000-02-01 A B C 40.1 11.1 -55.6 178.7 49.8 -196.7 70.1 -47.3 -106.8 -21.8 -102.6 -72.9
3: 0001 2000-03-01 A B C -62.5 -168.7 83.8 15.3 -113.8 125.4 42.6 -29.5 89.5 87.8 82.2 68.9
4: 0001 2000-04-01 A B C 55.4 -6.2 -30.6 -38.0 -69.5 -20.8 -126.5 216.9 120.8 -112.3 -40.3 -46.7
5: 0001 2000-05-01 A B C 78.0 -8.3 25.3 -2.9 -4.3 136.9 -22.6 151.6 -154.9 58.5 12.4 21.6
---
95996: 0800 2009-08-01 A B C 136.5 79.6 -140.4 -216.5 35.3 31.4 -57.0 78.1 -53.3 -18.0 60.9 100.7
95997: 0800 2009-09-01 A B C 33.8 -12.5 -17.2 90.8 -24.7 -19.3 101.4 -39.1 139.4 15.5 -33.5 17.7
95998: 0800 2009-10-01 A B C 56.8 -121.2 242.4 -1.0 -9.9 78.2 34.6 31.8 -51.7 -11.1 45.0 89.1
95999: 0800 2009-11-01 A B C 158.8 -101.9 -271.8 -21.1 -24.6 108.0 185.3 82.3 -54.9 116.4 149.2 -30.4
96000: 0800 2009-12-01 A B C 34.9 -34.0 186.4 -3.7 -26.8 97.0 8.7 84.5 -35.5 -106.2 -165.0 188.0
数据
OP 没有提供可复现的例子,所以我们自己编造假数据:
library(data.table)
library(lubridate)
# 10 years of startmonths times 12 returnmonths times 800 names
nn <- 800L
ns <- 10L * 12L
nr <- 12L
# cross join to create all combinations
DT <- CJ(name = sprintf("%04i", seq_len(nn)),
startmonth = seq(as.Date("2000-01-01"), length.out = ns, by = "month"),
returnmonth = seq_len(nr)
)
# compute returnmonth as sequence of 12 months after each startmonth
DT[, returnmonth := startmonth + months(returnmonth)][]
# append other data columns
DT[, paste0("d", 1:3) := .("A", "B", "C")][]
set.seed(123L)
DT[, return := round(100 * rnorm(nrow(DT)), 1L)][]
str(DT)
Classes ‘data.table’ and 'data.frame': 1152000 obs. of 7 variables:
$ name : chr "0001" "0001" "0001" "0001" ...
$ startmonth : Date, format: "2000-01-01" "2000-01-01" "2000-01-01" "2000-01-01" ...
$ returnmonth: Date, format: "2000-02-01" "2000-03-01" "2000-04-01" "2000-05-01" ...
$ d1 : chr "A" "A" "A" "A" ...
$ d2 : chr "B" "B" "B" "B" ...
$ d3 : chr "C" "C" "C" "C" ...
$ return : num -56 -23 155.9 7.1 12.9 ...
- attr(*, ".internal.selfref")=<externalptr>