有条件地删除 R 中的行
Deleting rows in R conditionally
我有一个数据,其中第一列是一堆 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 行并删除其余行
对于每个 'ID' 组的 selecting 具有最小值 'Number' 的行,我们可以使用一种按组聚合的功能。 base R
选项是 aggregate
。对于 aggregate
,我们可以使用 'formula' 方法或使用 by
参数指定分组 elements/variables 的 list
。使用 formula
方法,我们得到每个 'ID'.
的 'Number' 的 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]
或者这也可以通过 setorder
到 order
'Number' 列并使用 unique
和 by
选项到 select第一个非重复的 'ID' 行。 (来自@David Arenburgs 的评论)
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'的最小值'Number'获取行,你可以使用which.min
。使用 .I
将获取行索引,可用于对行进行子集化。
setDT(df1)[df1[, .I[which.min(Number)], by = ID]$V1]
或者对于 dplyr
我们使用 slice
过滤掉每个 'ID'[=39= 的 min
值为 'Number' 的行]
df1 %>%
group_by(ID) %>%
slice(which.min(Number))
或者
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
我有一个数据,其中第一列是一堆 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 行并删除其余行
对于每个 'ID' 组的 selecting 具有最小值 'Number' 的行,我们可以使用一种按组聚合的功能。 base R
选项是 aggregate
。对于 aggregate
,我们可以使用 'formula' 方法或使用 by
参数指定分组 elements/variables 的 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]
或者这也可以通过 setorder
到 order
'Number' 列并使用 unique
和 by
选项到 select第一个非重复的 'ID' 行。 (来自@David Arenburgs 的评论)
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'的最小值'Number'获取行,你可以使用which.min
。使用 .I
将获取行索引,可用于对行进行子集化。
setDT(df1)[df1[, .I[which.min(Number)], by = ID]$V1]
或者对于 dplyr
我们使用 slice
过滤掉每个 'ID'[=39= 的 min
值为 'Number' 的行]
df1 %>%
group_by(ID) %>%
slice(which.min(Number))
或者
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