使用列号在数据表中进行分组而不是在R中进行分组

时间:2016-08-11 19:27:46

标签: r matrix data.table grouping

我的代码需要灵活,我在分组时无法对列名进行硬编码。因此,我想硬编码列号来进行分组,因为这些很容易指定范围变化。 (第1列到第X列左右,而不是使用列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。

2 个答案:

答案 0 :(得分:2)

也许只需选择names(DF)列号,并结合eval(parse(...))

useColNums <- function(data, a, b) {
  n <- names(data) 
  y <- n[a[1]]
  x <- n[a[2]]
  groupby <- sprintf("list(%s)", paste(n[b], collapse=","))
  argmax <-  sprintf("list(%1$s=max(%1$s),%2$s=%2$s[which.max(%1$s)])", y, x)
  data[, eval(parse(text=argmax)), by=eval(parse(text=groupby))]  
}

x <- useColNums(DF, 2:1, 3:4)
y <- DF[, list(Y=max(Y),X=X[which.max(Y)]), by=list(Z, Q)]
identical(x, y)
# [1] TRUE

答案 1 :(得分:0)

您可以将grep与您的代码结合使用:

> 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 = data.table(DF)
> coly <- na
> DF[, list(Y=max(Y),X=X[which.max(Y)]), by=c(col1 <- names(DF)[grep("Q", colnames(DF))], names(DF)[grep("Z", colnames(DF))])]
    Q Z Y  X
 1: 4 3 1  1
 2: 2 1 0  2
 3: 4 5 0  3
 4: 2 5 1 19
 5: 5 5 0  5
 6: 1 0 1  6
 7: 0 3 0  7
 8: 4 2 1  8
 9: 5 2 0 10
10: 3 4 0 11
11: 4 1 1 13
12: 3 1 0 14
13: 0 2 1 17
14: 1 4 0 18
15: 1 2 0 20