r:部分重塑为宽表,但保留键列
我希望通过展开r:部分重塑为宽表,但保留键列,r,dataframe,data-structures,reshape,R,Dataframe,Data Structures,Reshape,我希望通过展开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
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')
非常感谢您的任何建议 这里有一个
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
这里有一个选择:
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
注意:包装
reformate2
已停止使用和维护。因此,建议改为使用data.table::dcast()
或其他替代方法,如tidyr
您是否查看了tidyr::spread
?如果存在多个匹配项,如dt[dt$day==“2019-01-02”&dt$agent==“B”
?我将它们相加!数据结构是我想要的,但似乎单元格中滞后列下的是滞后值,而不是销售值。有什么办法可以修吗?太好了!我是否有可能用N/A或Null替换0?当然。例如,将fun.aggregate=sum
替换为fun.aggregate=function(x){if(length(x))sum(x),否则NA_real}
可能要添加您使用的库。仅供参考,我认为reformae2
软件包正在deprecated@Sotos这段代码既适用于restrape2::dcast()
version 1.4.3,也适用于data.table::dcast()
,我通常使用并且(据我所知)正在积极维护它。是的,data.table::dcast()
很好。我刚才评论了一下重塑,因为OP正在使用它。我建议您在库中添加关于数据的注释。表一