【发布时间】:2021-11-11 03:52:12
【问题描述】:
我有一个按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
这是我想要/预期的输出:
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
我不知道为什么会发生这种情况。我唯一的另一个想法是分别为每个变量执行此操作,然后将结果合并在一起。但这似乎是解决问题的一种非常低效的方法。
任何帮助将不胜感激!
【问题讨论】:
-
我很好奇“提取代表每个变量最大值的行”。根据您提供的链接,您的结果是否需要是矩阵列表?
-
您的预期输出是什么?你需要
dt[, lapply(.SD, max), .SDcols = variables, by = "ID"]吗? -
有关 tidyverse 解决方案,请查看
slice_max()。由于您可能会为每个变量的最大值选择不同的行,因此您需要指定所需输出的格式。有很多可能性... -
更简单:
dt1[, lapply(.SD, which.max), by = "ID"]。不需要参数.SDcols。而且我没有看到输出有任何问题。 -
@RonakShah 和 Limey:我已经用我想要的输出编辑了这个问题。此外,Ronak 的解决方案有效。为什么
max可以工作,而which.max不行?
标签: r data.table lapply