我正在尝试分别对几个(实际上是数百个)组(而不是所有组的所有组合)执行指标计数。我将通过简化的示例来演示它:
假设我有该数据集
data<-cbind(c(1,1,1,2,2,2)
,c(1,1,2,2,2,3)
,c(3,2,1,2,2,3))
> data
[,1] [,2] [,3]
[1,] 1 1 3
[2,] 1 1 2
[3,] 1 2 1
[4,] 2 2 2
[5,] 2 2 2
[6,] 2 3 3
和一个指标
some_indicator<-c(1,0,0,1,0,1)
然后我想在没有循环的情况下运行(例如按列应用),例如,
aggregate(some_indicator,list(data[,1]),sum)
aggregate(some_indicator,list(data[,2]),sum)
aggregate(some_indicator,list(data[,3]),sum)
这将生成以下结果:
[,1] [,2] [,3]
[1,] 1 1 0
[2,] 2 1 1
[3,] 0 1 2
即对于每一列(列之间的值子集不会有太大变化),按值对指标进行计数并将其合并。
目前我是通过列循环来编写它的,但我需要更有效的方法,因为列很多并且需要一个多小时。
提前致谢, 迈克尔。
最佳答案
1) tapply tapply
的第一个参数是 data
,每一列都替换为 some_indicator
。第二个参数表示我们希望按数据中的组和列号进行分组。
result <- tapply(replace(data, TRUE, some_indicator), list(data, col(data)), sum)
replace(unname(result), is.na(result), 0)
对于问题中显示的输入,最后一行给出:
[,1] [,2] [,3]
[1,] 1 1 0
[2,] 2 1 1
[3,] 0 1 2
1a) tapply 一个稍长的 tapply
解决方案如下。 fun
将一列作为其参数,并使用 tapply
使用该列作为组对 some_indicator
中的组进行求和;但是,不同的列可能有不同的组集,因此为了确保它们都具有相同的组集(以便以后对齐),我们实际上按 factor(x, levs)
进行分组。 sapply
将 fun
应用于 data
的每一列。由于 data
是一个矩阵,所以需要 as.data.frame
,因此如果我们要应用,sapply
将应用于每个元素而不是每一列就这样。
levs <- levels(factor(data))
fun <- function(x) tapply(some_indicator, factor(x, levs), sum)
result <- sapply(as.data.frame(data), fun)
replace(unname(result), is.na(result), 0)
2) xtabs 这与 tapply
解决方案非常相似。它确实具有以下优点:(1) sum
由 xtabs
隐含,因此不需要指定,而且 (2) 未填充的单元格用 0 填充,而不是 NA 消除将 NA 替换为 0 的额外步骤。另一方面,我们必须使用 c
将公式的每个组件分解为向量,因为与 tapply
不同,xtabs
公式不接受矩阵:
result <- xtabs(c(replace(data, TRUE, some_indicator)) ~ c(data) + c(col(data)))
dimnames(result) <- NULL
对于问题中的数据,给出:
> result
[,1] [,2] [,3]
[1,] 1 1 0
[2,] 2 1 1
[3,] 0 1 2
修订修订了tapply
解决方案并添加了xtabs
解决方案。
关于r - 如何使用 R 通过多个单独的组进行相同的字段聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23388335/