【问题标题】:R - Modify column value depending on first occurence of another columnR - 根据另一列的第一次出现修改列值
【发布时间】:2018-09-25 13:07:32
【问题描述】:

假设我有一个包含 2 列类似于此列的文件:

     ID   Order
      2       1
     10       2
     70       3
     85       4
     70       5
    213       6
      2       7
    293       8
     10       9
    313      10
    ...     ...

IDs 包含 1 到 1000 之间的数字,每个数字出现 4 次。 在Order 中有从 1 到 4000 的数字。

在 R 中是否可以修改 Order 列,对于以下 3 个相同的 ID,它将 Order 替换为对应于第一次出现的 Order?对于示例数据集,它将例如输出以下内容:

     ID   Order
      2       1
     10       2
     70       3
     85       4
     70       3
    213       6
      2       1
    293       8
     10       2
    313      10
    ...     ...

【问题讨论】:

    标签: r row multiple-columns


    【解决方案1】:

    您可以使用dplyr 库轻松完成此操作。您可以按 ID 分组,然后使用mutate 函数查找每个 ID 的最小订单。

    library(dplyr)
    df %>% 
      group_by(ID) %>% 
      mutate(Order = min(Order)) %>% 
      ungroup()
    
    # A tibble: 10 x 2
          ID Order
       <int> <dbl>
     1     2     1
     2    10     2
     3    70     3
     4    85     4
     5    70     3
     6   213     6
     7     2     1
     8   293     8
     9    10     2
    10   313    10
    

    【讨论】:

      【解决方案2】:

      基础R:

      df$Order <- with(df, ave(Order, ID, FUN = `[`, 1))
      

      数据表:

      library(data.table)
      setDT(df)
      
      df[, Order := Order[1], ID]
      
      
      #      ID Order
      #  1:   2     1
      #  2:  10     2
      #  3:  70     3
      #  4:  85     4
      #  5:  70     3
      #  6: 213     6
      #  7:   2     1
      #  8: 293     8
      #  9:  10     2
      # 10: 313    10
      

      【讨论】:

        【解决方案3】:

        另一种选择是过滤第一次出现,然后重新加入原始 ID 的完整列表

        library(dplyr)
        library(readr)
        library(purrr)
        
        df <- read_table2(" ID   Order
              2       1
             10       2
             70       3
             85       4
             70       5
            213       6
              2       7
            293       8
             10       9
            313      10")
        
        df %>% 
          filter(!duplicated(ID)) %>% 
          list(., df %>% select(ID)) %>%
          reduce(full_join, by = "ID")
        #> # A tibble: 10 x 2
        #>       ID Order
        #>    <int> <int>
        #>  1     2     1
        #>  2     2     1
        #>  3    10     2
        #>  4    10     2
        #>  5    70     3
        #>  6    70     3
        #>  7    85     4
        #>  8   213     6
        #>  9   293     8
        #> 10   313    10
        

        reprex package (v0.2.0) 于 2018 年 9 月 25 日创建。

        【讨论】:

          猜你喜欢
          • 2019-06-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多