根据标准月度周期重新调整宽度

时间:2015-01-07 00:11:08

标签: r dataframe reshape

我正在使用长格式的大型数据集(在使用融合之后),我现在想要在df的每一行上运行计算之前切换到宽格式

这个长格式数据集(“dflong”)有7列:name,returnmonth,startmonth,descriptive1,descriptive2,descriptive3和return。

我使用long格式,因为每个name / startmonth对都有多个returnmonth。具体来说,我为每个名字和startmonth提供了接下来的12个月的回报,而startmonths则为10年。这使df变大:它有120万行和7列。

我接下来想要的是为每个名称/ startmonth标准化接下来的12个月,并且有一个宽格式,其中最右边的12列是月份startmonth + 1,startmonth + 2等的回报,不管是什么实际月份是。但我不能只使用下面的公式,因为returnmonths本身不同,我想这将创建一个非常非常宽的df,我不想要。 (此时,当我尝试运行它时,它只是给我一个错误)。

dfwide=reshape(dflong,idvar=c("name","startmonth","descriptive1","descriptive2","descriptive3"),timevar="returnmonth",direction="wide")

是否有重塑和其他工具的组合,这些工具可以让我从长到宽转换,但也不考虑返回来自的特定月份。这将形成一个长但可管理的n行* 17列数据帧,以便使用。

非常感谢你的帮助。

1 个答案:

答案 0 :(得分:0)

到目前为止,这个老问题还没有得到答案。

OP要求从长格式转换为宽格式,其中返回值应排列在12列中,代表每个startmonth之后的12个月。

这可以使用dcast()包中的rowid()data.table函数来完成。

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>