将行更改为列并按分组

时间:2019-06-03 14:29:59

标签: r dataframe spread

我有一个相对较大的DF,现在需要一种使行成列的方法。

我的DF看起来像这样:

AID FNAME FVALUE
1   A     10
1   B     12
1   C     16
2   A     10
2   E     4
3   F     10
3   G     13

,依此类推。并非所有行都具有所有特征。所以我喜欢这样的最终输出:

AID A B C D E F G H 
1   10 12 16 NULL NULL NULL NULL
2   10 NULL NULL NULL 4 NULL NULL NULL
3   NULL NULL NULL NULL NULL 10 13 NULL

我已经尝试了传播:

wide_DF <- unite_DF %>% spread(FNAME, FVALUE)

但是我得到了错误:

  

错误:输出的每一行都必须由键的唯一组合来标识。

我也尝试过将数据分组并插入一个新的唯一列:

unite_DF  %>% group_by(AID) %>% mutate(ind = row_number()) %>% spread(FNAME, FVALUE) %>% select(Name, Value)

但是在这里我也遇到同样的错误。我该怎么办?

2 个答案:

答案 0 :(得分:2)

您似乎正在寻找reshape

AID <- c(1, 1, 1, 2, 2, 3, 3)
FNAME <- c("A", "B", "C", "A", "E", "F", "G")
FVALUE <- c(10, 12, 16, 10, 4, 10, 13)

df <- data.frame(AID, FNAME, FVALUE)

df_wide <- reshape(df, direction = "wide", idvar = "AID", v.names = "FVALUE", timevar = "FNAME")

答案 1 :(得分:1)

在将“ FNAME”转换为spread并指定factor后,我们可以使用levels,并在spread中使用drop = FALSE避免使用没有组合

library(tidyverse)
unite_DF %>% 
  mutate(FNAME = factor(FNAME, levels = LETTERS[1:8])) %>% 
  spread(FNAME, FVALUE, drop = FALSE)
#   AID  A  B  C  D  E  F  G  H
#1   1 10 12 16 NA NA NA NA NA
#2   2 10 NA NA NA  4 NA NA NA
#3   3 NA NA NA NA NA 10 13 NA

数据

unite_DF <- structure(list(AID = c(1L, 1L, 1L, 2L, 2L, 3L, 3L), FNAME = c("A", 
"B", "C", "A", "E", "F", "G"), FVALUE = c(10L, 12L, 16L, 10L, 
4L, 10L, 13L)), class = "data.frame", row.names = c(NA, -7L))