【发布时间】:2016-08-11 19:27:45
【问题描述】:
我的代码需要灵活,我不能在分组时在列名中硬编码。因此,我想对列号进行硬编码以进行分组,因为这些很容易指定超出范围的更改。 (第 1 列到 X 左右,而不是使用 cols 1,2,..X 的名称)
示例数据集:
set.seed(007)
DF <- data.frame(X=1:20, Y=sample(c(0,1), 20, TRUE), Z=sample(0:5, 20, TRUE), Q =sample(0:5, 20, TRUE))
DF
X Y Z Q
1 1 1 3 4
2 2 0 1 2
3 3 0 5 4
4 4 0 5 2
5 5 0 5 5
6 6 1 0 1
7 7 0 3 0
8 8 1 2 4
9 9 0 5 5
10 10 0 2 5
11 11 0 4 3
12 12 0 1 4
13 13 1 1 4
14 14 0 1 3
15 15 0 2 4
16 16 0 5 2
17 17 1 2 0
18 18 0 4 1
19 19 1 5 2
20 20 0 2 1
一个分组(由 Z 和 Q)找到最大化 Y 的 X,并返回两者:
DF =data.table(DF)
DF[, list(Y=max(Y),X=X[which.max(Y)]), by=list(Z, Q)]
结果:
DF[, list(Y=max(Y),X=X[which.max(Y)]), by=list(Z, Q)]
Z Q Y X
1: 3 4 1 1
2: 1 2 0 2
3: 5 4 0 3
4: 5 2 1 19
5: 5 5 0 5
6: 0 1 1 6
7: 3 0 0 7
8: 2 4 1 8
9: 2 5 0 10
10: 4 3 0 11
11: 1 4 1 13
12: 1 3 0 14
13: 2 0 1 17
14: 4 1 0 18
15: 2 1 0 20
由于我的代码的性质,我想纯粹使用列号来执行此操作。此外,如果还有另一列,我可能希望按该额外列进行分组。而且我还想在第一部分中返回另一个 argmax。
【问题讨论】:
-
最好不要使用列号,但如果需要,您可能需要对名称进行子集化,即
setDT(DF)[, list(Y=max(Y),X=X[which.max(Y)]), by = c(names(DF)[3:4])] -
@akrun 我还需要 X 和 Y 部分基于列名,因为我使用的列名必须取决于我正在运行的许多模拟的规范。实现这一点非常困难...... –
-
您可以简单地保存原始列名,将它们临时重命名为预定约定,然后在分组后将原始列名写回。这可以通过编程来完成,以允许任意数量的列名。
-
你的意思是像下面的解决方案@Hack-R?问题是我希望它也适用于 X 和 Y。
-
我猜也可以
DF[, list(Y=max(.SD[[2]]),X=.SD[[1]][which.max(.SD[[2]])]), by=c(names(DF)[3:4])]。另外,请不要DF =data.table(DF)。只需setDT(DF)或首先使用DF <- data.table(...创建数据集即可
标签: r matrix data.table grouping