【问题标题】:r: partially reshaping to wide table but keep key columnr:部分重塑为宽表但保留关键列
【发布时间】:2019-04-23 14:39:57
【问题描述】:

我想通过展开Lag 将我当前的数据框转换为一个宽表,但同时保留变量agent。宽表的大多数单元格中的数字是sales

library(reshape2)
set.seed(123)

day = rep(seq(as.Date('2019/01/01'), as.Date('2019/01/04'), by="day"), each = 5)
agent = sample(c('A', 'B', 'C'), 20, replace = T)
sales = rnorm(20, 100, 30) 
Lag = sample(0:3, 20, replace=T)

dt = data.frame(day, sales, agent, Lag)

理想情况下,结果如下所示:

我尝试了以下方法,但这些都不起作用。

dcast(dt, day~Lag, value.var='sales')
dcast(dt, day~Lag+agent, value.var='sales')

非常感谢任何建议!

【问题讨论】:

  • 你看tidyr::spread了吗?
  • 如果像dt[dt$day == "2019-01-02"& dt$agent == "B", ]这样的匹配不止一个,你想做什么?
  • @sindri_baldur 我会把它们加起来!

标签: r dataframe data-structures reshape


【解决方案1】:

这是一种选择:

library(reshape2)
dcast(dt, day + agent ~ paste0("lag_", Lag), value.var='sales', fun.aggregate = sum)

#           day agent     lag_0     lag_1     lag_2     lag_3
# 1  2019-01-01     A   0.00000   0.00000 136.72245   0.00000
# 2  2019-01-01     B   0.00000 112.02314   0.00000   0.00000
# 3  2019-01-01     C 110.79441 103.32048   0.00000  83.32477
# 4  2019-01-02     A   0.00000 153.60739   0.00000   0.00000
# 5  2019-01-02     B   0.00000  85.81626   0.00000 235.97619
# 6  2019-01-02     C   0.00000   0.00000   0.00000  41.00149
# 7  2019-01-03     A   0.00000  81.24882   0.00000   0.00000
# 8  2019-01-03     B  78.13326   0.00000  93.46075   0.00000
# 9  2019-01-03     C   0.00000   0.00000  69.21987  67.96529
# 10 2019-01-04     A   0.00000 190.98950 104.60119   0.00000
# 11 2019-01-04     C 187.01365   0.00000   0.00000   0.00000

注意:包裹reshape2 正在停止使用和维护。因此建议改用data.table::dcast() 或其他替代方案,例如tidyr

【讨论】:

  • 太完美了!我有没有机会用 N/A 或 Null 替换 0?
  • 当然。例如用fun.aggregate = function(x) {if (length(x)) sum(x) else NA_real_}替换fun.aggregate = sum
  • 可能想要添加您使用的library。仅供参考,我认为 reshape2 包正在被弃用
  • @Sotos 此代码适用于 reshape2::dcast() 版本 1.4.3 和 data.table::dcast(),我通常使用并且(据我所知)正在积极维护。
  • 是的,data.table::dcast() 很好。我刚刚评论了重塑,因为 OP 正在使用它。我建议您在库中添加有关 data.table 的注释
【解决方案2】:

这是dplyr / tidyr 替代方案。使用 tidyr 中的 spread 可以生成所需的表单:

library(tidyr)
dt %>% spread(Lag, unique(Lag))

使用dplyr,您可以相应地填充列:

dt %>% spread(Lag, unique(Lag), fill = 0) %>% mutate(`0` = sales * `0`) %>% mutate(`1` = sales * `1`) %>% mutate(`2` = sales * `2`/2) %>% mutate(`3` = sales * `3`/3)

          day     sales agent 0         1         2         3
1  2019-01-01  83.32477     C 0   0.00000   0.00000  83.32477
2  2019-01-01 103.32048     C 0 103.32048   0.00000   0.00000
3  2019-01-01 110.79441     C 0   0.00000   0.00000   0.00000
4  2019-01-01 112.02314     B 0 112.02314   0.00000   0.00000
5  2019-01-01 136.72245     A 0   0.00000 136.72245   0.00000
6  2019-01-02  41.00149     C 0   0.00000   0.00000  41.00149
7  2019-01-02  85.81626     B 0  85.81626   0.00000   0.00000
8  2019-01-02 114.93551     B 0   0.00000   0.00000 114.93551
9  2019-01-02 121.04068     B 0   0.00000   0.00000 121.04068
10 2019-01-02 153.60739     A 0 153.60739   0.00000   0.00000

【讨论】:

  • 数据结构是我想要的,但似乎 Lag 列下的单元格中的内容是 Lag 的值而不是 sales 的值。有什么办法可以解决吗?
猜你喜欢
  • 2021-08-04
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
  • 2016-08-26
  • 2016-03-20
  • 1970-01-01
相关资源
最近更新 更多