1

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

我想对我的数据框中的每四行进行平均,即我的输出数据集应该有 20 列,其中V1,V2,V3…V20300 行包含 4 组数据的平均值。

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

有没有一种有效的方法来做到这一点?我想使用 apply 系列的函数,并希望避免循环。

4

1 回答 1

2

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

你也可以使用glie。

 gl(10, 4, 10)

对于数据集,它应该是

 gl(1200, 4, 1200)

现在,您可以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)

然后使用lapplywithcolMeans获取每个列表元素的列均值并使用 rbinddo.call(rbind,..)

或者

summarise_eachdplyr

 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
于 2014-09-19T09:12:05.040 回答