R用tidyr传播多个列

Ric*_*cky 90 r dataframe dplyr tidyr

拿这个样本变量

df <- data.frame(month=rep(1:3,2),
                 student=rep(c("Amy", "Bob"), each=3),
                 A=c(9, 7, 6, 8, 6, 9),
                 B=c(6, 7, 8, 5, 6, 7))
Run Code Online (Sandbox Code Playgroud)

我可以使用spreadtidyr将其更改为宽格式.

> df[, -4] %>% spread(student, A)
  month Amy Bob
1     1   9   8
2     2   7   6
3     3   6   9
Run Code Online (Sandbox Code Playgroud)

但我怎么能传播两个值,例如既AB,使得输出是一样的东西

  month Amy.A Bob.A Amy.B Bob.B
1     1     9     8     6     5
2     2     7     6     7     6
3     3     6     9     8     7
Run Code Online (Sandbox Code Playgroud)

Dav*_*urg 173

这是一个简单而有效的解决方案 data.table

library(data.table) ## v >= 1.9.6
dcast(setDT(df), month ~ student, value.var = c("A", "B")) 
#    month Amy_A Bob_A Amy_B Bob_B
# 1:     1     9     8     6     5
# 2:     2     7     6     7     6
# 3:     3     6     9     8     7
Run Code Online (Sandbox Code Playgroud)

或者可能的tidyr解决方案

df %>% 
  gather(variable, value, -(month:student)) %>%
  unite(temp, student, variable) %>%
  spread(temp, value)

#   month Amy_A Amy_B Bob_A Bob_B
# 1     1     9     6     8     5
# 2     2     7     7     6     6
# 3     3     6     8     9     7
Run Code Online (Sandbox Code Playgroud)

  • `pivot_wider(data = df, id_cols = Month, names_from = Student, values_from = c("A", "B"))` 应该在 tidyr 1.0.0 或更高版本中工作 (3认同)
  • ivot_wider 也可以在不带引号的变量名称(在本例中为 A 和 B)的情况下工作,即ivot_wider(data = df, id_cols = Month, names_from = Student, Values_from = c(A, B)) (2认同)