library(tidyverse)続けて、pivot_widerで複数列に対応する場合を考えてみましょう。
例えば、
dat <- tibble(
age = c("<20","20-30","30-40",">40","<20","20-30","30-40",">40"),
grp = c("A","B","A","B","A","B","A","B"),
sex = c("m","m","m","m","f","f","f","f"),
val = c(1:8)
)
dat# A tibble: 8 × 4
age grp sex val
<chr> <chr> <chr> <int>
1 <20 A m 1
2 20-30 B m 2
3 30-40 A m 3
4 >40 B m 4
5 <20 A f 5
6 20-30 B f 6
7 30-40 A f 7
8 >40 B f 8
このデータ、横持ちにしたときに、列名の部分を
dat %>%
pivot_wider(
id_cols = grp,
names_from = age,
values_from = val
)Warning: Values from `val` are not uniquely identified; output will contain list-cols.
• Use `values_fn = list` to suppress this warning.
• Use `values_fn = {summary_fun}` to summarise duplicates.
• Use the following dplyr code to identify duplicates.
{data} %>%
dplyr::group_by(grp, age) %>%
dplyr::summarise(n = dplyr::n(), .groups = "drop") %>%
dplyr::filter(n > 1L)
# A tibble: 2 × 5
grp `<20` `20-30` `30-40` `>40`
<chr> <list> <list> <list> <list>
1 A <int [2]> <NULL> <int [2]> <NULL>
2 B <NULL> <int [2]> <NULL> <int [2]>
重複するデータがあるのでListが作られていますが、
dat %>%
pivot_wider(
id_cols = grp,
names_from = c(age, sex),
values_from = val
)# A tibble: 2 × 9
grp `<20_m` `20-30_m` `30-40_m` `>40_m` `<20_f` `20-30_f` `30-40_f` `>40_f`
<chr> <int> <int> <int> <int> <int> <int> <int> <int>
1 A 1 NA 3 NA 5 NA 7 NA
2 B NA 2 NA 4 NA 6 NA 8
names_fromに複数変数を与えてあげると問題が起こりません。
尚、変数名の間は、初期設定では_が挿入されていますが、
dat %>%
pivot_wider(
id_cols = grp,
names_from = c(age, sex),
values_from = val,
names_sep = "@@"
)# A tibble: 2 × 9
grp `<20@@m` `20-30@@m` `30-40@@m` `>40@@m` `<20@@f` `20-30@@f` `30-40@@f`
<chr> <int> <int> <int> <int> <int> <int> <int>
1 A 1 NA 3 NA 5 NA 7
2 B NA 2 NA 4 NA 6 NA
# ℹ 1 more variable: `>40@@f` <int>
で変更可能です。
dat %>%
pivot_wider(
id_cols = grp,
names_from = c(age, sex),
values_from = val,
names_sep = "―――",
values_fill = 0
)# A tibble: 2 × 9
grp `<20―――m` `20-30―――m` `30-40―――m` `>40―――m` `<20―――f` `20-30―――f`
<chr> <int> <int> <int> <int> <int> <int>
1 A 1 0 3 0 5 0
2 B 0 2 0 4 0 6
# ℹ 2 more variables: `30-40―――f` <int>, `>40―――f` <int>
後は、値がNAでなくて、何か別の値で埋めたい場合はvalues_fillに値を与えてあげると自動的に埋めてくれます。