【问题标题】:Deleting rows in R conditionally有条件地删除R中的行
【发布时间】:2015-08-31 07:55:06
【问题描述】:

我有一个数据,其中第一列是一堆 ID 号(有些重复),第二列只是一堆数字。我需要一种方法,根据第二列中的最小数字将每个 ID 号仅保留一次。

Row#   ID   Number
1      10     180
2      12     167
3      12     182
4      12     135
5      15     152
6      15     133

例如:我只想在此处保留第 1、4 和 6 行并删除其余的

【问题讨论】:

    标签: r conditional delete-row


    【解决方案1】:

    要为每个“ID”组选择具有最小“编号”的行,我们可以使用按组聚合功能之一。 base R 选项是 aggregate。使用aggregate,我们可以使用“公式”方法或使用by 参数指定分组元素/变量的list。使用formula 方法,我们得到每个“ID”的“数字”min 值。

    aggregate(Number~ID, df1, FUN=min)
    

    或者我们可以使用更快的选项data.table。在这里,我们将 'data.frame' 转换为 'data.table' (setDT(df1)),按 'ID' 分组,我们得到“Number”的min 值。

    library(data.table)
    setDT(df1)[, list(Number=min(Number)), by = ID] 
    

    或者这也可以使用setorderorder 'Number' 列并使用uniqueby 选项来选择第一个非重复的'ID' 行。 (来自@David Arenburgs 的 cmets)

     unique(setorder(setDT(df1), Number), by = "ID")
    

    或者使用dplyr,我们按“ID”分组并获得带有summarise的子集行。

    library(dplyr)
    df1 %>%
       group_by(ID) %>%
       summarise(Number= min(Number))
    

    或者我们可以使用sqldf语法来获取数据子集。

    library(sqldf)
    sqldf('select ID,
            min(Number) as Number
            from df1 
            group by ID')
    

    更新

    如果有多个列,并且您想根据每个“ID”的“数字”最小值获取行,则可以使用which.min。使用.I 将获得行索引,并可用于对行进行子集化。

    setDT(df1)[df1[,  .I[which.min(Number)], by = ID]$V1]
    

    或者使用dplyr,我们使用slice 过滤出每个“ID”的min 值为“Number”的行

    df1 %>% 
        group_by(ID) %>%
        slice(which.min(Number))
    

    【讨论】:

    • unique(setorder(setDT(df1), Number), by = "ID")。我还认为您需要which.min 而不是min,因为似乎OP 总是希望每个ID 保留一行。顺便说一句,很好的sqldf 解决方案:)
    • @DavidArenburg 谢谢,min 只保留单个值,但当有更多列时,which.min 会更通用。
    【解决方案2】:

    或者

    do.call(rbind, 
    lapply(split(df1, df1$ID), function(x) subset(x, Number == min(Number))))
    
    #ID Number
    #10 10    180
    #12 12    135
    #15 15    133
    

    【讨论】:

      猜你喜欢
      • 2021-06-09
      • 2014-05-04
      • 2020-08-11
      • 2012-06-05
      • 2021-11-25
      • 2019-04-07
      • 2016-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多