将数据从长格式重塑为宽格式 - 不止一个变量
Reshape data from long to wide format - more than one variable
我正在尝试使用 reshape2 中的 dcast
函数将我的数据从长公式重塑为宽公式。
objective 是在 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 |
+---------+------+--------+--------------+------------+
我的 objective 是将年份列传递给其余列(增长、失业和人口)。我正在使用下面的 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 |
+---------+-------------+-------------------+-----------------+-------------+-------------------+-----------------+
如果您没有使用 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
这是
的作品
正在将所有值堆叠到一列中...
正在将变量名称和年份列合并为一个列...
然后将新栏目展开为宽格式
OP 给出的 dcast()
语句与最新版本的 data.table
包几乎完美配合,因为这些允许多个测量变量与 dcast()
和 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
这与 的结果相同。
但是,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
请注意 cross join 函数 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
我正在尝试使用 reshape2 中的 dcast
函数将我的数据从长公式重塑为宽公式。
objective 是在 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 |
+---------+------+--------+--------------+------------+
我的 objective 是将年份列传递给其余列(增长、失业和人口)。我正在使用下面的 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 |
+---------+-------------+-------------------+-----------------+-------------+-------------------+-----------------+
如果您没有使用 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
这是
的作品正在将所有值堆叠到一列中...
正在将变量名称和年份列合并为一个列...
然后将新栏目展开为宽格式
OP 给出的 dcast()
语句与最新版本的 data.table
包几乎完美配合,因为这些允许多个测量变量与 dcast()
和 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
这与
但是,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
请注意 cross join 函数 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