【问题标题】:Gather duplicating rows收集重复的行
【发布时间】:2020-03-25 06:49:11
【问题描述】:

新手再次需要帮助。

我遇到了重复行的转置。

我的数据结构如下:

id date client status  agent_1 agent_2 agent_3...agent_10  flag_1 Flag_2 Flag_3  order_num_1 Order_num_2
1  xxx   yyy   01        A1        C2    E3
2  xxx  yyyy   02        B1        D2    F3
3  xxx  yyy    03        C1        E2    G3

我想要:

id  date   client  status  agent flag  order_num
1    xxx    yyy     01      A1
1    xxx   yyyy     01      C2
1    xxx   yyy      01      E3
2
2
3
3

客户信息将重复,_1 到 _10 列将变为行。

我有下面的代码。第一个收集代理运行良好,但是当我运行下一个收集时,它会复制我的 df,以及所有可能的组合。

 df1 <- df %>% 
      select( id,
              created_on,
              date_reported,
              client_name,
              status_code, 
              starts_with('agent'), 
              starts_with('Flag'), 
              starts_with('order_num'),
              starts_with('order_date'),
              starts_with('manufacturer'))  %>%
      gather(key, value = "agent", starts_with('agent')) %>%
      select(-starts_with('key'))%>%
      filter(!is.na(agent))
      gather(key1, value = "flag", starts_with('Flag'))%>%
      gather(key2, value = "order_num", starts_with('order_num'))  %>%
      gather(key3, value = "order_date", starts_with('order_date'))   %>%
      gather(key4, value = "manufacturer", starts_with('manufacturer')) 

我做错了什么?我试过group_by代理,但没用。

【问题讨论】:

    标签: r transpose


    【解决方案1】:

    不使用gather,而是使用最新的tidyr 包中的pivot_longer(本质上是它的替代品)。

    示例数据:

    df <- data.frame(
      id = c(1,1,1,2,2,2),
      date = sample(seq(as.Date("2018-01-01"), as.Date("2019-01-01"), by="day"), 6),
      client = c(rep('y', 6)),
      status = c(1,2,3,1,2,3),
      agent_1 = c('A1', 'B1', 'C1', 'D1', 'E1', 'F1'),
      agent_2 = c('C2', 'D2', 'E2', 'F2', 'G2', 'H2'),
      agent_3 = c('E3', 'F3', 'G3', 'H3', 'I3', 'J3'),
      flag_1 = c('H4', 'I4', 'J4', 'K4', 'L4', 'M4'),
      flag_2 = c('K5', 'L5', 'M5', 'N5', 'O5', 'P5'),
      flag_3 = c('Q6', 'R6', 'S6', 'T6', 'U6', 'V6')
    )
    
      id       date client status agent_1 agent_2 agent_3 flag_1 flag_2 flag_3
    1  1 2018-01-06      y      1      A1      C2      E3     H4     K5     Q6
    2  1 2018-09-25      y      2      B1      D2      F3     I4     L5     R6
    3  1 2018-07-20      y      3      C1      E2      G3     J4     M5     S6
    4  2 2018-05-23      y      1      D1      F2      H3     K4     N5     T6
    5  2 2018-08-01      y      2      E1      G2      I3     L4     O5     U6
    6  2 2018-10-16      y      3      F1      H2      J3     M4     P5     V6
    

    您可以执行以下操作:

    df %>%
      pivot_longer(cols = c(starts_with("agent"), starts_with("flag")),
                   names_to = c(".value", "group"),
                   names_sep = "_")
    

    这会给你:

    # A tibble: 18 x 7
          id date       client status group agent flag 
       <dbl> <date>     <fct>   <dbl> <chr> <fct> <fct>
     1     1 2018-01-06 y           1 1     A1    H4   
     2     1 2018-01-06 y           1 2     C2    K5   
     3     1 2018-01-06 y           1 3     E3    Q6   
     4     1 2018-09-25 y           2 1     B1    I4   
     5     1 2018-09-25 y           2 2     D2    L5   
     6     1 2018-09-25 y           2 3     F3    R6   
     7     1 2018-07-20 y           3 1     C1    J4   
     8     1 2018-07-20 y           3 2     E2    M5   
     9     1 2018-07-20 y           3 3     G3    S6   
    10     2 2018-05-23 y           1 1     D1    K4   
    11     2 2018-05-23 y           1 2     F2    N5   
    12     2 2018-05-23 y           1 3     H3    T6   
    13     2 2018-08-01 y           2 1     E1    L4   
    14     2 2018-08-01 y           2 2     G2    O5   
    15     2 2018-08-01 y           2 3     I3    U6   
    16     2 2018-10-16 y           3 1     F1    M4   
    17     2 2018-10-16 y           3 2     H2    P5   
    18     2 2018-10-16 y           3 3     J3    V6
    

    编辑:其他替代方案包括reshape(基数R)和meltdata.table)。

    对于meltid 在这种情况下将包含id 列名的向量(或者可以使用列号 1:4),measure 变量是要融化的列名向量 -在这种情况下,使用基于正则表达式的pattern^agent_^flag_),并使用value.name 作为您要用于这些新变量的最终列名(在这种情况下,agent 和 @ 987654339@)。

    library(data.table)
    
    melt(setDT(df), 
         id = c("id", "date", "client", "status"), 
         measure = patterns("^agent_", "^flag_"),
         value.name = c("agent", "flag"))[order(id, date)]
    

    【讨论】:

    • 嗨,本,感谢您的帮助。我忘了说我不能使用pivot_longer,因为我的工作场所不允许在不更新R版本的情况下更新包。有没有其他相当于pivot_longer的功能?
    猜你喜欢
    • 2021-04-20
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 2012-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-01
    相关资源
    最近更新 更多