分组整个数据集并进行聚合

时间:2014-09-19 08:51:04

标签: r apply mean tapply

我有一个包含20个变量V1,V2,V3......V20和1,200行的数据集。

我希望数据框中每四行平均一次,即输出数据集应该有20列 包含V1,V2,V3…V20和300行,包含4个组中的平均数据。

我不能使用tapply因为我必须一次输入1个变量;我想一次平均所有20个变量。

有一种有效的方法吗?我想使用来自apply family的功能 喜欢避免循环。

1 个答案:

答案 0 :(得分:2)

lapplycolMeans

一起使用
 set.seed(42)
 dat <- as.data.frame(matrix(sample(1:20, 20*1200, replace=TRUE), ncol=20))
 n <- seq_len(nrow(dat))

 res <- do.call(rbind,lapply(split(dat, (n-1)%/%4 +1),colMeans, na.rm=TRUE))
 dim(res)
 #[1] 300  20

解释

这里的想法是创建一个分组变量,将数据集拆分为列表中数据集的子集,条件是1:4行进入第一个子集,5:8到第二个子集,并且.. 。,最后一个子集将有297:300。为了便于理解,使用行的子集。假设您的数据集有10行:

  n1 <- seq_len(10)
  n1
  #[1]  1  2  3  4  5  6  7  8  9 10

  (n1-1) %/%4 #created a numeric index to split by group
  # [1] 0 0 0 0 1 1 1 1 2 2

我在上面添加了1,从1开始而不是0

  (n1-1) %/%4 +1
  #[1] 1 1 1 1 2 2 2 2 3 3

你也可以使用gl ie。

 gl(10, 4, 10)

对于数据集,它应该是

 gl(1200, 4, 1200)

现在,您可以通过新创建的分组索引或数据集{/ 1}} split

n1

对于 split(n1,(n1-1) %/%4 +1) # you can check the result of this

的10行的子集
dataset

然后使用 split(dat[1:10,], (n1-1) %/%4 +1) lapply来获取每个列表元素的列方式,并使用colMeans

对其进行rbind

来自do.call(rbind,..)

summarise_each

dplyr

使用 library(dplyr) res2 <- dat %>% mutate(N= (row_number()-1)%/%4+1) %>% group_by(N) %>% summarise_each(funs(mean=mean(., na.rm=TRUE))) %>% select(-N) dim(res2) #[1] 300 20 all.equal(as.data.frame(res), as.data.frame(res2), check.attributes=FALSE) #[1] TRUE

data.table