Reshape data from long to wide format - more than one variable [duplicate]

谁说胖子不能爱 提交于 2019-11-29 13:02:58
Uwe

The dcast() statement given by the OP works almost perfect with the recent versions of the data.table package as these allow for multiple measure variables to be used with dcast() and melt():

library(data.table)   # CRAN version 1.10.4
setDT(world)   # coerce to data.table
data_wide <- dcast(world, Country ~ Year, 
                   value.var = c("Growth", "Unemployment", "Population"))

data_wide
#   Country Growth_2015 Growth_2016 Growth_2017 Unemployment_2015 Unemployment_2016 Unemployment_2017 Population_2015
#1:       A         2.0         4.0         4.5               8.3               8.1               8.1              40
#2:       B         3.0         3.5         4.4               9.2               9.0               8.4              32
#3:       C         2.5         3.7         4.3               9.1               9.0               8.5              30
#4:       D         1.5         3.1         4.2               6.1               5.3               5.2              27
#   Population_2016 Population_2017
1:            42.0            42.5
2:            32.5            33.0
3:            31.0            30.0
4:            29.0            30.0

This is the same result as the tidyr solution.


However, the OP has requested a specific column order for his ideal solution where the different measure variables of each year are grouped together.

If the proper order of columns is important, there are two ways to achieve this. The first approach is to reorder the columns appropriately using setcolorder():

new_ord <- CJ(world$Year, c("Growth","Unemployment","Population"), 
              sorted = FALSE, unique = TRUE)[, paste(V2, V1, sep = "_")]
setcolorder(data_wide, c("Country", new_ord))

data_wide
#   Country Growth_2015 Unemployment_2015 Population_2015 Growth_2016 Unemployment_2016 Population_2016 Growth_2017
#1:       A         2.0               8.3              40         4.0               8.1            42.0         4.5
#2:       B         3.0               9.2              32         3.5               9.0            32.5         4.4
#3:       C         2.5               9.1              30         3.7               9.0            31.0         4.3
#4:       D         1.5               6.1              27         3.1               5.3            29.0         4.2
#   Unemployment_2017 Population_2017
#1:               8.1            42.5
#2:               8.4            33.0
#3:               8.5            30.0
#4:               5.2            30.0

Note the the cross join function CJ() is used to create the cross product of the vectors.


The other approach to achieve the desired column order is to melt and recast:

molten <- melt(world, id.vars = c("Country", "Year"))
dcast(molten, Country ~ Year + variable)
#   Country 2015_Growth 2015_Unemployment 2015_Population 2016_Growth 2016_Unemployment 2016_Population 2017_Growth
#1:       A         2.0               8.3              40         4.0               8.1            42.0         4.5
#2:       B         3.0               9.2              32         3.5               9.0            32.5         4.4
#3:       C         2.5               9.1              30         3.7               9.0            31.0         4.3
#4:       D         1.5               6.1              27         3.1               5.3            29.0         4.2
#   2017_Unemployment 2017_Population
#1:               8.1            42.5
#2:               8.4            33.0
#3:               8.5            30.0
#4:               5.2            30.0

If you're not married to a dcast solution, I personally find tidyr easier.

library(tidyr)
df <- df %>% 
     gather(key, value, -Country, -Year) %>%  
     unite(new.col, c(key, Year)) %>%   
     spread(new.col, value) 

Result

  Country Growth_2015 Growth_2016 Growth_2017 Population_2015 Population_2016 Population_2017 Unemployment_2015 Unemployment_2016 Unemployment_2017
1       A         2.0         4.0         4.5              40            42.0            42.5               8.3               8.1               8.1
2       B         3.0         3.5         4.4              32            32.5            33.0               9.2               9.0               8.4
3       C         2.5         3.7         4.3              30            31.0            30.0               9.1               9.0               8.5
4       D         1.5         3.1         4.2              27            29.0            30.0               6.1               5.3               5.2

This works by

Stacking all values into one column...

Combining variable name and year columns into a single column...

The new column is then spread into wide format

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!