【问题标题】:Expanding columns associated with a categorical variable into multiple columns with dplyr/tidyr while retaining id variable [duplicate]使用 dplyr/tidyr 将与分类变量关联的列扩展为多个列,同时保留 id 变量 [重复]
【发布时间】:2018-02-02 22:53:15
【问题描述】:

我有一个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 中并且需要删除。

可以使用tidyr 中的函数(例如spread)来完成此扩展吗?

【问题讨论】:

  • 旁注。我认为tribbleframe_data 的最新术语。请参阅?frame_data 详细信息:“frame_data() 是 tribble() 的旧名称。它最终将被淘汰。”

标签: r dplyr tidyr


【解决方案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 

【讨论】:

  • 而基数 R 是 reshape(as.data.frame(dfTall), idvar="id", timevar="x", direction="wide", sep="_"),因为 reshape 也处理多个变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-17
  • 2020-10-22
  • 1970-01-01
  • 1970-01-01
  • 2021-01-06
  • 2015-07-14
相关资源
最近更新 更多