有条件地删除R中的行

Swa*_*nny 6 conditional r delete-row

我有一个数据,第一列是一堆ID号(有些重复),第二列只是一堆数字.我需要一种方法来保持每个ID号只基于第二列中的最小数字.

Row#   ID   Number
1      10     180
2      12     167
3      12     182
4      12     135
5      15     152
6      15     133
Run Code Online (Sandbox Code Playgroud)

例如:我只想在这里保留第1,第4和第6行并删除其余部分

akr*_*run 14

为了选择每个'ID'组具有最小'Number'的行,我们可以使用group by聚合功能之一.一个base R选项是aggregate.使用aggregate,我们可以使用'formula'方法或使用参数指定list分组元素/变量by.使用该formula方法,我们得到min每个'ID'的'Number'值.

aggregate(Number~ID, df1, FUN=min)
Run Code Online (Sandbox Code Playgroud)

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

library(data.table)
setDT(df1)[, list(Number=min(Number)), by = ID] 
Run Code Online (Sandbox Code Playgroud)

或者,这可以与也做setorder对order了"数字"列,并使用unique带有by选项来选择的第一个非重复的"ID"行.(来自@David Arenburgs的评论)

 unique(setorder(setDT(df1), Number), by = "ID")
Run Code Online (Sandbox Code Playgroud)

或者使用dplyr,我们按'ID'分组并获取子集行summarise.

library(dplyr)
df1 %>%
   group_by(ID) %>%
   summarise(Number= min(Number))
Run Code Online (Sandbox Code Playgroud)

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

library(sqldf)
sqldf('select ID,
        min(Number) as Number
        from df1 
        group by ID')
Run Code Online (Sandbox Code Playgroud)

更新

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

setDT(df1)[df1[,  .I[which.min(Number)], by = ID]$V1]
Run Code Online (Sandbox Code Playgroud)

或者dplyr我们使用slice过滤掉min每个"ID"值为"Number" 的行

df1 %>% 
    group_by(ID) %>%
    slice(which.min(Number))
Run Code Online (Sandbox Code Playgroud)