按行广义聚合

时间:2014-04-29 21:47:43

标签: r aggregate

我想按行汇总。我知道如何做到这一点,并在这里回答了其他人提出的几个问题。但是,我想概括聚合公式,理想情况下不会使聚合行的顺序与它们在原始数据集中首次出现的顺序不同。

以下是一个示例集:

my.data <- read.table(text = '
    0 0 0 1
    0 0 0 1
    2 2 2 2
    2 2 2 2
    0 4 0 0
    0 4 0 0
    2 2 0 0
    2 2 0 0
    2 2 0 0
    2 2 0 0
', header = FALSE)

和我想要的结果:

desired.result <- read.table(text = '
    0 0 0 1 2
    2 2 2 2 2
    0 4 0 0 2
    2 2 0 0 4
', header = FALSE)

这是获得答案的一种方法,尽管行不是按原始顺序排列的:

my.data[,(ncol(my.data)+1)] = 1

aggregate(V5 ~ V1 + V2 + V3 + V4, FUN = sum, data=my.data)

  V1 V2 V3 V4 V5
1  2  2  0  0  4
2  0  4  0  0  2
3  0  0  0  1  2
4  2  2  2  2  2

这是一个不成功的尝试来概括聚合公式:

with(my.data, aggregate(my.data[,ncol(my.data)], by = list(paste0('V', seq(1, ncol(my.data)-1))), FUN = sum))

结果的顺序不如概括那么重要。

感谢您的任何建议。

3 个答案:

答案 0 :(得分:2)

由于结果表明所需结果只是唯一行的频率计数,因此您可以/应该使用table(如评论中所述)。 table在其参数和factor上使用factor,如果未指定“级别”,则sort的输入为uniqueunique不会sort)指定级别。因此,要table“查看”您的级别(即所需的行顺序),您需要在明确指定的table上调用factor

tmp = do.call(paste, my.data)
as.data.frame(table(tmp))
#      tmp Freq
#1 0 0 0 1    2
#2 0 4 0 0    2
#3 2 2 0 0    4
#4 2 2 2 2    2    
res = table(factor(tmp, unique(tmp)))
as.data.frame(res)
#     Var1 Freq
#1 0 0 0 1    2
#2 2 2 2 2    2
#3 0 4 0 0    2
#4 2 2 0 0    4

您可以利用as.data.frame.table并使用以下调用,而不是调用unique.data.frame - 您的行已被连接 -

data.frame(unique(my.data), unclass(res))
#  V1 V2 V3 V4 unclass.res.
#1  0  0  0  1            2
#3  2  2  2  2            2
#5  0  4  0  0            2
#7  2  2  0  0            4

答案 1 :(得分:1)

可能有必要提一下count包中的plyr函数也可以快速聚合。虽然,你仍然会失去原来的行顺序。

> library(plyr)
> x <- count(my.data)
> x
##   V1 V2 V3 V4 freq
## 1  0  0  0  1    2
## 2  0  4  0  0    2
## 3  2  2  0  0    4
## 4  2  2  2  2    2

要以desired.result显示的方式订购表格(以及从@alexis_laz借用代码段),

> pst <- do.call(paste, my.data)
> x[order(x$freq, as.factor(unique(pst))), ]
##   V1 V2 V3 V4 freq
## 1  0  0  0  1    2
## 4  2  2  2  2    2
## 2  0  4  0  0    2
## 3  2  2  0  0    4

答案 2 :(得分:1)

我喜欢发布的答案,特别是@alexis_laz的答案,因为我倾向于选择基础R。但是,这是使用aggregate的一般答案。输出中行的顺序与它们在原始数据集中首次出现的顺序不同,但至少对行进行了计算:

我从@ alexis_laz的评论中借用了.中的aggregate

my.data <- read.table(text = '

    0 0 0 1
    0 0 0 1
    2 2 2 2
    2 2 2 2
    0 4 0 0
    0 4 0 0
    2 2 0 0
    2 2 0 0
    2 2 0 0
    2 2 0 0

', header = FALSE)

my.data

my.count = rep(1, nrow(my.data))
my.count

aggregate(my.count ~ ., FUN = sum, data=my.data)

  V1 V2 V3 V4 my.count
1  2  2  0  0        4
2  0  4  0  0        2
3  0  0  0  1        2
4  2  2  2  2        2