使用tidyr在R中展开多列数据

108

使用此示例变量

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))

我可以使用tidyr中的spread函数,将此数据转换为宽格式。

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

但是我该如何传播两个值,例如 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
1个回答

204

这里有一个可能既简单又非常高效的解决方案,使用 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

或者是一个可能的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

编辑 2019年10月22日

@gjabel在评论中提到的,更新的tidyr版本(v1.0.0+)现在已经具有pivot_widerpivot_longer函数(目前处于成熟状态),因此,一种更新的方法将是:

pivot_wider(data = df, 
            id_cols = month, 
            names_from = student, 
            values_from = c("A", "B"))
# # A tibble: 3 x 5
#     month A_Amy A_Bob B_Amy B_Bob
#     <int> <dbl> <dbl> <dbl> <dbl>
#   1     1     9     8     6     5
#   2     2     7     6     7     6
#   3     3     6     9     8     7

1
@PolarBear 你想如何处理重复项?你想求和吗?平均值?尝试使用 data.table 解决方案,并将 fun.aggregate = sum 添加到 dcast 中。 - David Arenburg
1
@PolarBear spreadgather并不适用于应用函数。你可能需要使用dplyr。或者,你可以像我之前建议的那样使用dcast。如果你对此有强烈的感觉,也可以发布一个新问题。 - David Arenburg
1
我为这些进行了基准测试:https://dev59.com/zF0a5IYBdhLWcg3w88k0#54889598 - hplieninger
4
pivot_wider(data = df, id_cols = month, names_from = student, values_from = c("A", "B")) 应该可以在 tidyr 1.0.0 或以上的版本中使用。 - guyabel
2
pivot_wider函数也可以不使用变量名称的引号(在本例中为A和B),即pivot_wider(data = df, id_cols = month, names_from = student, values_from = c(A, B))。 - jlp
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接