对多个变量按组提取最大值对应的行
Extract row corresponding to maximum value by group for multiple variables
我有一个按 ID
分组的数据框,每个 ID
有多行,还有几个变量 a
、b
、c
等
这是一个玩具示例:
dt <- structure(list(ID = c(1, 1, 2, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5,
5, 5, 6, 6, 6, 6, 6, 6, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10), a = c(1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1), b = c(1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1), c = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), d = c(1, 1, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0,
0, 0, 0, 0, 1, 1), e = c(0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1), f = c(1,
1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 0, 1, 1, 1, 1), g = c(1, 1, 1, 1, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1), h = c(1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1), i = c(1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
0, 0, 0, 0, 1, 1)), row.names = c(NA, -31L), class = c("tbl_df",
"tbl", "data.frame"))
对于每个 ID
,我想提取代表每个变量最大值的行(取最大值的第一个或最后一个实例不是问题)。当只考虑一个变量 for example 时,有很多例子可以说明如何做到这一点。但是,我很难将其应用于多个变量。
这是我解决问题的尝试(使用 data.table
和 lapply
):
library(data.table)
setDT(dt)
variables = colnames(dt[, 2:10])
dt_max = dt[, lapply(.SD, which.max), .SDcols = variables, by = "ID"]
看看这会产生什么,似乎是对值进行求和,而不是为每个值提取最大值 ID
:
ID a b c d e f g h i
1: 1 1 1 1 1 2 1 1 1 1
2: 2 1 1 1 1 1 1 1 1 1
3: 3 1 1 1 1 5 1 1 2 1
4: 4 1 1 1 1 1 1 1 1 1
5: 5 1 1 1 1 1 3 1 1 1
6: 6 1 1 1 1 1 1 1 1 1
7: 7 1 1 1 1 1 1 1 1 1
8: 8 1 1 1 1 1 2 1 2 2
9: 9 1 1 1 1 1 2 1 1 1
10: 10 1 1 1 1 1 1 1 1 1
这是我的 desired/expected 输出:
ID a b c d e f g h i
1: 1 1 1 1 1 1 1 1 1 1
2: 2 1 1 1 0 0 1 1 0 1
3: 3 1 1 1 0 1 1 1 1 1
4: 4 1 1 1 0 0 1 1 0 0
5: 5 1 1 1 1 1 1 1 0 0
6: 6 1 1 1 1 1 1 1 0 1
7: 7 1 1 1 1 1 0 1 0 0
8: 8 1 1 1 1 0 1 1 1 1
9: 9 1 1 1 0 1 1 1 0 0
10: 10 1 1 1 1 1 1 1 1 1
我不知道为什么会这样。我唯一的其他想法是分别对每个变量执行此操作,然后将结果合并在一起。但这似乎是一种非常低效的解决问题的方法。
如有任何帮助,我们将不胜感激!
max
和 which.max
是两个不同的函数,做不同的事情。 max
会给出向量中的最大值,而 which.max
会给出向量中最大值的位置。
x <- 4:1
max(x)
#[1] 4
which.max(x)
#[1] 1
此处 which.max
returns 1 因为 4 出现在向量 x
.
的第一个位置
因此,如果您需要多个列中的 max
个值,您应该使用 max
而不是 which.max
。
library(data.table)
setDT(dt)
variables = colnames(dt[, 2:10])
dt[, lapply(.SD, max), .SDcols = variables, ID]
# ID a b c d e f g h i
# 1: 1 1 1 1 1 1 1 1 1 1
# 2: 2 1 1 1 0 0 1 1 0 1
# 3: 3 1 1 1 0 1 1 1 1 1
# 4: 4 1 1 1 0 0 1 1 0 0
# 5: 5 1 1 1 1 1 1 1 0 0
# 6: 6 1 1 1 1 1 1 1 0 1
# 7: 7 1 1 1 1 1 0 1 0 0
# 8: 8 1 1 1 1 0 1 1 1 1
# 9: 9 1 1 1 0 1 1 1 0 0
#10: 10 1 1 1 1 1 1 1 1 1
我有一个按 ID
分组的数据框,每个 ID
有多行,还有几个变量 a
、b
、c
等
这是一个玩具示例:
dt <- structure(list(ID = c(1, 1, 2, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5,
5, 5, 6, 6, 6, 6, 6, 6, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10), a = c(1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1), b = c(1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1), c = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), d = c(1, 1, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0,
0, 0, 0, 0, 1, 1), e = c(0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1), f = c(1,
1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 0, 1, 1, 1, 1), g = c(1, 1, 1, 1, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1), h = c(1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1), i = c(1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
0, 0, 0, 0, 1, 1)), row.names = c(NA, -31L), class = c("tbl_df",
"tbl", "data.frame"))
对于每个 ID
,我想提取代表每个变量最大值的行(取最大值的第一个或最后一个实例不是问题)。当只考虑一个变量 for example 时,有很多例子可以说明如何做到这一点。但是,我很难将其应用于多个变量。
这是我解决问题的尝试(使用 data.table
和 lapply
):
library(data.table)
setDT(dt)
variables = colnames(dt[, 2:10])
dt_max = dt[, lapply(.SD, which.max), .SDcols = variables, by = "ID"]
看看这会产生什么,似乎是对值进行求和,而不是为每个值提取最大值 ID
:
ID a b c d e f g h i
1: 1 1 1 1 1 2 1 1 1 1
2: 2 1 1 1 1 1 1 1 1 1
3: 3 1 1 1 1 5 1 1 2 1
4: 4 1 1 1 1 1 1 1 1 1
5: 5 1 1 1 1 1 3 1 1 1
6: 6 1 1 1 1 1 1 1 1 1
7: 7 1 1 1 1 1 1 1 1 1
8: 8 1 1 1 1 1 2 1 2 2
9: 9 1 1 1 1 1 2 1 1 1
10: 10 1 1 1 1 1 1 1 1 1
这是我的 desired/expected 输出:
ID a b c d e f g h i
1: 1 1 1 1 1 1 1 1 1 1
2: 2 1 1 1 0 0 1 1 0 1
3: 3 1 1 1 0 1 1 1 1 1
4: 4 1 1 1 0 0 1 1 0 0
5: 5 1 1 1 1 1 1 1 0 0
6: 6 1 1 1 1 1 1 1 0 1
7: 7 1 1 1 1 1 0 1 0 0
8: 8 1 1 1 1 0 1 1 1 1
9: 9 1 1 1 0 1 1 1 0 0
10: 10 1 1 1 1 1 1 1 1 1
我不知道为什么会这样。我唯一的其他想法是分别对每个变量执行此操作,然后将结果合并在一起。但这似乎是一种非常低效的解决问题的方法。
如有任何帮助,我们将不胜感激!
max
和 which.max
是两个不同的函数,做不同的事情。 max
会给出向量中的最大值,而 which.max
会给出向量中最大值的位置。
x <- 4:1
max(x)
#[1] 4
which.max(x)
#[1] 1
此处 which.max
returns 1 因为 4 出现在向量 x
.
因此,如果您需要多个列中的 max
个值,您应该使用 max
而不是 which.max
。
library(data.table)
setDT(dt)
variables = colnames(dt[, 2:10])
dt[, lapply(.SD, max), .SDcols = variables, ID]
# ID a b c d e f g h i
# 1: 1 1 1 1 1 1 1 1 1 1
# 2: 2 1 1 1 0 0 1 1 0 1
# 3: 3 1 1 1 0 1 1 1 1 1
# 4: 4 1 1 1 0 0 1 1 0 0
# 5: 5 1 1 1 1 1 1 1 0 0
# 6: 6 1 1 1 1 1 1 1 0 1
# 7: 7 1 1 1 1 1 0 1 0 0
# 8: 8 1 1 1 1 0 1 1 1 1
# 9: 9 1 1 1 0 1 1 1 0 0
#10: 10 1 1 1 1 1 1 1 1 1