1

我正在尝试使用dcast中的函数将我的数据从长公式重塑为宽公式。

目标是在value.var参数中使用不同的变量,但 R 不允许我在其中使用多个值。

有没有其他方法可以解决它?我看过其他类似的问题,但我找不到类似的例子。

这是我当前的数据集:

+---------+------+--------+--------------+------------+
| Country | Year | Growth | Unemployment | Population |
+---------+------+--------+--------------+------------+
| A       | 2015 |      2 |          8.3 |         40 |
| B       | 2015 |      3 |          9.2 |         32 |
| C       | 2015 |    2.5 |          9.1 |         30 |
| D       | 2015 |    1.5 |          6.1 |         27 |
| A       | 2016 |      4 |          8.1 |         42 |
| B       | 2016 |    3.5 |            9 |       32.5 |
| C       | 2016 |    3.7 |            9 |         31 |
| D       | 2016 |    3.1 |          5.3 |         29 |
| A       | 2017 |    4.5 |          8.1 |       42.5 |
| B       | 2017 |    4.4 |          8.4 |         33 |
| C       | 2017 |    4.3 |          8.5 |         30 |
| D       | 2017 |    4.2 |          5.2 |         30 |
+---------+------+--------+--------------+------------+

我的目标是将年份列传递给其余列(增长、失业和人口)。我正在使用下面的 dcast 功能。

data_wide <- dcast(world, country  ~ year,
     value.var=c("Growth","Unemployment","Population"))

理想的结果

+---------+-------------+-------------------+-----------------+-------------+-------------------+-----------------+
| Country | Growth_2015 | Unemployment_2015 | Population_2015 | Growth_2016 | Unemployment_2016 | Population_2016 |
+---------+-------------+-------------------+-----------------+-------------+-------------------+-----------------+
| A       |           2 |               8.3 |              40 |           4 |               8.1 |              42 |
| B       |           3 |               9.2 |              32 |         3.5 |                 9 |            32.5 |
| C       |         2.5 |               9.1 |              30 |         3.7 |                 9 |              31 |
| D       |         1.5 |               6.1 |              27 |         3.1 |               5.3 |              29 |
+---------+-------------+-------------------+-----------------+-------------+-------------------+-----------------+
4

2 回答 2

5

如果您没有与 dcast 解决方案结婚,我个人觉得 tidyr 更容易。

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

结果

  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

这通过

将所有值堆叠在一列...

将变量名称和年份列组合成一列...

然后将新列展开为宽格式

于 2017-05-14T16:03:24.350 回答
0

OP 给出的dcast()声明与最新版本的软件包几乎完美配合,data.table因为这些版本允许将多个度量变量与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

tidyr这与解决方案的结果相同。


但是,OP 已为他的理想解决方案要求特定的列顺序,其中每年的不同测量变量组合在一起。

如果列的正确顺序很重要,有两种方法可以实现这一点。第一种方法是使用适当地重新排序列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

请注意,交叉连接函数 CJ()用于创建向量的叉积。


实现所需列顺序的另一种方法是熔化和重铸

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
于 2017-05-17T06:42:23.507 回答