代码之家  ›  专栏  ›  技术社区  ›  Nettle

使用dplyr整理多个列

  •  2
  • Nettle  · 技术社区  · 7 年前

    gather spread 难以想象的步骤。

    library(tidyverse)
    df <- data_frame(month_1 = c("Jan", "Feb", "Mar", "Jun"),
                            score_1 = c(4, 5, 6, 4),
                            month_2 = c("Jan", "Mar", NA, NA),
                            score_2 = c(3, 2, NA, NA),
                            month_3 = c("Feb", "Mar", "Jun", NA),
                            score_3 = c(8, 7, 4, NA))
    
    # A tibble: 4 x 6
      month_1 score_1 month_2 score_2 month_3 score_3
      <chr>     <dbl> <chr>     <dbl> <chr>     <dbl>
    1 Jan           4 Jan           3 Feb           8
    2 Feb           5 Mar           2 Mar           7
    3 Mar           6 NA           NA Jun           4
    4 Jun           4 NA           NA NA           NA
    

    我期望的结果是:

    id month score
    1  Jan   4
    1  Feb   5
    1  Mar   6
    1  Jun   4
    2  Jan   3
    2  Mar   2
    3  Feb   8  
    3  Mar   7
    3  Jun   4
    

    melt(setDT(df), measure = patterns("^month", "^score"))
    

    但由于没有等效的dplyr函数,我知道需要几个 传播 . 看起来我下面的解决方案应该行得通,但是第二个 出错:

    df %>% 
      gather(key, value) %>% 
      mutate(id = parse_number(key),
             key = str_replace(key, "_[0-9]", "")) %>% 
      spread(key, value )
    

    在把这个标为复制品之前,请试一试。类似的问题在现有列中具有唯一的id。这个例子在头中有id。

    1 回复  |  直到 7 年前
        1
  •  1
  •   andrew_reece    7 年前

    你可以处理 month score 列,然后用 purrr::map_dfc

    map_dfc(c("month", "score"), 
            ~ df %>%
              select_at(vars(matches(.x))) %>%
              gather(key, !!.x) %>%
              separate(key, c("col", "id"), sep="_")) %>% 
      filter(complete.cases(.)) %>%
      select(id, month, score)
    
    # A tibble: 9 x 3
     id   month score 
    <chr> <chr> <chr>
    1 1     Jan   4    
    2 1     Feb   5    
    3 1     Mar   6    
    4 1     Jun   4    
    5 2     Jan   3    
    6 2     Mar   2    
    7 3     Feb   8    
    8 3     Mar   7    
    9 3     Jun   4    
    

    说明:

    • map_dfc 迭代字符串值“month”和“score”,将当前值引用为 .x . 这个 dfc 后缀执行 cbind 在迭代输出上。
    • select_at 仅选择以开头的列
    • gather values 带有 x
    • separate key 分为两列,包含列类型(对应于 价值)和 id 号码。
    • 一旦映射和列绑定完成,我们 filter 删除缺少的值和 select 我们的目标列。