【问题标题】:Reshape to wide based on standard monthly periods根据标准月度周期重塑为宽
【发布时间】:2015-01-07 00:11:08
【问题描述】:

我正在处理一个长格式的大型数据集(使用melt之后),现在我想在对df的每一行运行计算之前切换到宽格式

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

我使用长格式,因为每个名称/开始月份对都有多个返回月份。具体来说,我有每个名称和 startmonth 的未来 12 个月的回报,而 startmonths 跨越 10 年。这使得 df 很大:它有 120 万行和那 7 列。

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

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

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

非常感谢您的帮助。

【问题讨论】:

  • 提供可重现的示例...否则,我假设您熟悉使用 reshape2 包进行熔化,熟悉从同一包中进行铸造。

标签: r dataframe reshape


【解决方案1】:

这个老问题至今没有答案。

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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-26
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 1970-01-01
    • 2019-09-19
    相关资源
    最近更新 更多