将lapply 与colMeans 一起使用
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 即。
gl(10, 4, 10)
对于数据集,应该是
gl(1200, 4, 1200)
现在,您可以通过新创建的分组索引或数据集splitn1
split(n1,(n1-1) %/%4 +1) # you can check the result of this
对于dataset的10行子集
split(dat[1:10,], (n1-1) %/%4 +1)
然后使用lapply 和colMeans 获取每个列表元素的列均值并使用do.call(rbind,..) 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
library(data.table)
DT1 <- setDT(dat)[, N:=(seq_len(.N)-1)%/%4 +1][,
lapply(.SD, mean, na.rm=TRUE), by=N][,N:=NULL]
dim(DT1)
#[1] 300 20