扩大与分类变量相关联的成与dplyr / tidyr多个列的列,同时保留id变量[重复](Expan

2019-09-29 23:14发布

这个问题已经在这里有一个答案:

  • ř扩频的多个列与tidyr [重复] 1个回答

我有一个data.frame ,看起来像这样:

dfTall <- frame_data(
    ~id, ~x, ~y, ~z,
      1, "a", 4, 5,
      1, "b", 6, 5,
      2, "a", 5, 4,
      2, "b", 1, 9)

我希望把它变成这样:

dfWide <- frame_data(
    ~id, ~y_a, ~y_b, ~z_a, ~z_b,
      1,    4,    6,    5,    5,
      2,    5,    1,    4,    9)

目前,我这样做

dfTall %>%
    split(., .$x) %>%
    mapply(function(df,name) 
        {df$x <- NULL; names(df) <- paste(names(df), name, sep='_'); df}, 
        SIMPLIFY=FALSE, ., names(.)) %>%
    bind_cols() %>%
    select(-id_b) %>%
    rename(id = id_a)

在实践中,我将需要扩大(即,不只是数字列更大数量的yz )。 我目前的解决方案的工作,但它有问题,如事实的多个副本id变量都会进入最后data.frame和需要被删除。

这可以扩展使用功能,从完成tidyrspread

Answer 1:

这是可以做到的spread而不是在一个单一的步骤,因为它涉及多个列的值; 你可以先gather值列, unite手动头,然后spread

library(dplyr)
library(tidyr)

dfTall %>% 
    gather(col, val, -id, -x) %>% 
    unite(key, col, x) %>% 
    spread(key, val)

# A tibble: 2 x 5
#     id   y_a   y_b   z_a   z_b
#* <dbl> <dbl> <dbl> <dbl> <dbl>
#1     1     4     6     5     5
#2     2     5     1     4     9

如果你使用data.tabledcast支持多投值列:

library(data.table)
dcast(setDT(dfTall), id ~ x, value.var = c('y', 'z'))

#   id y_a y_b z_a z_b
#1:  1   4   6   5   5
#2:  2   5   1   4   9 


文章来源: Expanding columns associated with a categorical variable into multiple columns with dplyr/tidyr while retaining id variable [duplicate]
标签: r dplyr tidyr