使用 tidyr 重塑 table
Reshape table using tidyr
我有一个很大的 table,我正在尝试使用 tidyr 重塑它的长格式,我想更改为宽格式。 table 很大,事实证明这比我想象的要复杂。
table 看起来像这样
Codes areas var1 var2 var3
1111 1010 2 2 34
1112 1010 3 7 18
1113 1010 20 12 11
1114 1010 19 11 22
[...] [...] [...] [...] [...]
1111 1020 14 19 12
1112 1020 10 10 13
目标是使用宽格式变量在每个区域获得一行。
喜欢:
Area 1111Var1 1111Var2 111Var3 1112Var1 1112Var2 1112Var3
1010 2 2 34 3 7 18
到目前为止,我已经尝试在 tidyr 中传播和变异,但没有取得太大成功。
这里您需要三个整洁的步骤:
d %>%
gather(key, value, -Codes, -areas) %>%
unite(combined, Codes, key, sep = "") %>%
spread(combined, value)
其中 d
是您的数据。
解释步骤:
library(tidyr)
# setting up data
d <- readr::read_delim("Codes areas var1 var2 var3
1111 1010 2 2 34
1112 1010 3 7 18
1113 1010 20 12 11
1114 1010 19 11 22
1111 1020 14 19 12
1112 1020 10 10 13", delim = " ")
首先您需要收集 var1、var2、var3 列:
d %>%
gather(key, value, -Codes, -areas)
#> Source: local data frame [18 x 4]
#>
#> Codes areas key value
#> (int) (int) (fctr) (int)
#> 1 1111 1010 var1 2
#> 2 1112 1010 var1 3
#> 3 1113 1010 var1 20
#> 4 1114 1010 var1 19
#> 5 1111 1020 var1 14
#> 6 1112 1020 var1 10
#> 7 1111 1010 var2 2
#> 8 1112 1010 var2 7
#> 9 1113 1010 var2 12
#> 10 1114 1010 var2 11
#> 11 1111 1020 var2 19
#> 12 1112 1020 var2 10
#> 13 1111 1010 var3 34
#> 14 1112 1010 var3 18
#> 15 1113 1010 var3 11
#> 16 1114 1010 var3 22
#> 17 1111 1020 var3 12
#> 18 1112 1020 var3 13
然后使用 tidyr 的 unite
:
将它们与 Codes
列合并
d %>%
gather(key, value, -Codes, -areas) %>%
unite(combined, Codes, key, sep = "")
#> Source: local data frame [18 x 3]
#>
#> combined areas value
#> (chr) (int) (int)
#> 1 1111var1 1010 2
#> 2 1112var1 1010 3
#> 3 1113var1 1010 20
#> 4 1114var1 1010 19
#> 5 1111var1 1020 14
#> 6 1112var1 1020 10
#> 7 1111var2 1010 2
#> 8 1112var2 1010 7
#> 9 1113var2 1010 12
#> 10 1114var2 1010 11
#> 11 1111var2 1020 19
#> 12 1112var2 1020 10
#> 13 1111var3 1010 34
#> 14 1112var3 1010 18
#> 15 1113var3 1010 11
#> 16 1114var3 1010 22
#> 17 1111var3 1020 12
#> 18 1112var3 1020 13
现在 spread
将起作用:
d %>%
gather(key, value, -Codes, -areas) %>%
unite(combined, Codes, key, sep = "") %>%
spread(combined, value)
#> Source: local data frame [2 x 13]
#>
#> areas 1111var1 1111var2 1111var3 1112var1 1112var2 1112var3 1113var1
#> (int) (int) (int) (int) (int) (int) (int) (int)
#> 1 1010 2 2 34 3 7 18 20
#> 2 1020 14 19 12 10 10 13 NA
#> Variables not shown: 1113var2 (int), 1113var3 (int), 1114var1 (int),
#> 1114var2 (int), 1114var3 (int)
我可以通过以下方式做到这一点,但它可能不是 best/most 有效的
df <- read.table(header = TRUE, stringsAsFactors = FALSE, text = '
Codes areas var1 var2 var3
1111 1010 2 2 34
1112 1010 3 7 18
1113 1010 20 12 11
1114 1010 19 11 22
1111 1020 14 19 12
1112 1020 10 10 13')
df_new <-
df %>%
gather(var_type, var_value, -areas, -Codes) %>%
mutate(var_code = paste(Codes, var_type, sep = '_')) %>%
select(-Codes, -var_type) %>%
spread(var_code, var_value)
df_new
# areas 1111_var1 1111_var2 1111_var3 1112_var1 1112_var2 1112_var3 1113_var1 1113_var2 1113_var3 1114_var1 1114_var2 1114_var3
#1 1010 2 2 34 3 7 18 20 12 11 19 11 22
#2 1020 14 19 12 10 10 13 NA NA NA NA NA NA
希望对您有所帮助。
编辑
这是使用 unite
代替上述解决方案的版本,正如@David Robinson 的答案中所使用的那样。
df %>%
gather(var_type, var_value, -areas, -Codes) %>%
unite(NewCode, Codes, var_type, sep = '') %>%
spread(NewCode, var_value)
我有一个很大的 table,我正在尝试使用 tidyr 重塑它的长格式,我想更改为宽格式。 table 很大,事实证明这比我想象的要复杂。
table 看起来像这样
Codes areas var1 var2 var3
1111 1010 2 2 34
1112 1010 3 7 18
1113 1010 20 12 11
1114 1010 19 11 22
[...] [...] [...] [...] [...]
1111 1020 14 19 12
1112 1020 10 10 13
目标是使用宽格式变量在每个区域获得一行。
喜欢:
Area 1111Var1 1111Var2 111Var3 1112Var1 1112Var2 1112Var3
1010 2 2 34 3 7 18
到目前为止,我已经尝试在 tidyr 中传播和变异,但没有取得太大成功。
这里您需要三个整洁的步骤:
d %>%
gather(key, value, -Codes, -areas) %>%
unite(combined, Codes, key, sep = "") %>%
spread(combined, value)
其中 d
是您的数据。
解释步骤:
library(tidyr)
# setting up data
d <- readr::read_delim("Codes areas var1 var2 var3
1111 1010 2 2 34
1112 1010 3 7 18
1113 1010 20 12 11
1114 1010 19 11 22
1111 1020 14 19 12
1112 1020 10 10 13", delim = " ")
首先您需要收集 var1、var2、var3 列:
d %>%
gather(key, value, -Codes, -areas)
#> Source: local data frame [18 x 4]
#>
#> Codes areas key value
#> (int) (int) (fctr) (int)
#> 1 1111 1010 var1 2
#> 2 1112 1010 var1 3
#> 3 1113 1010 var1 20
#> 4 1114 1010 var1 19
#> 5 1111 1020 var1 14
#> 6 1112 1020 var1 10
#> 7 1111 1010 var2 2
#> 8 1112 1010 var2 7
#> 9 1113 1010 var2 12
#> 10 1114 1010 var2 11
#> 11 1111 1020 var2 19
#> 12 1112 1020 var2 10
#> 13 1111 1010 var3 34
#> 14 1112 1010 var3 18
#> 15 1113 1010 var3 11
#> 16 1114 1010 var3 22
#> 17 1111 1020 var3 12
#> 18 1112 1020 var3 13
然后使用 tidyr 的 unite
:
Codes
列合并
d %>%
gather(key, value, -Codes, -areas) %>%
unite(combined, Codes, key, sep = "")
#> Source: local data frame [18 x 3]
#>
#> combined areas value
#> (chr) (int) (int)
#> 1 1111var1 1010 2
#> 2 1112var1 1010 3
#> 3 1113var1 1010 20
#> 4 1114var1 1010 19
#> 5 1111var1 1020 14
#> 6 1112var1 1020 10
#> 7 1111var2 1010 2
#> 8 1112var2 1010 7
#> 9 1113var2 1010 12
#> 10 1114var2 1010 11
#> 11 1111var2 1020 19
#> 12 1112var2 1020 10
#> 13 1111var3 1010 34
#> 14 1112var3 1010 18
#> 15 1113var3 1010 11
#> 16 1114var3 1010 22
#> 17 1111var3 1020 12
#> 18 1112var3 1020 13
现在 spread
将起作用:
d %>%
gather(key, value, -Codes, -areas) %>%
unite(combined, Codes, key, sep = "") %>%
spread(combined, value)
#> Source: local data frame [2 x 13]
#>
#> areas 1111var1 1111var2 1111var3 1112var1 1112var2 1112var3 1113var1
#> (int) (int) (int) (int) (int) (int) (int) (int)
#> 1 1010 2 2 34 3 7 18 20
#> 2 1020 14 19 12 10 10 13 NA
#> Variables not shown: 1113var2 (int), 1113var3 (int), 1114var1 (int),
#> 1114var2 (int), 1114var3 (int)
我可以通过以下方式做到这一点,但它可能不是 best/most 有效的
df <- read.table(header = TRUE, stringsAsFactors = FALSE, text = '
Codes areas var1 var2 var3
1111 1010 2 2 34
1112 1010 3 7 18
1113 1010 20 12 11
1114 1010 19 11 22
1111 1020 14 19 12
1112 1020 10 10 13')
df_new <-
df %>%
gather(var_type, var_value, -areas, -Codes) %>%
mutate(var_code = paste(Codes, var_type, sep = '_')) %>%
select(-Codes, -var_type) %>%
spread(var_code, var_value)
df_new
# areas 1111_var1 1111_var2 1111_var3 1112_var1 1112_var2 1112_var3 1113_var1 1113_var2 1113_var3 1114_var1 1114_var2 1114_var3
#1 1010 2 2 34 3 7 18 20 12 11 19 11 22
#2 1020 14 19 12 10 10 13 NA NA NA NA NA NA
希望对您有所帮助。
编辑
这是使用 unite
代替上述解决方案的版本,正如@David Robinson 的答案中所使用的那样。
df %>%
gather(var_type, var_value, -areas, -Codes) %>%
unite(NewCode, Codes, var_type, sep = '') %>%
spread(NewCode, var_value)