【问题标题】:Grouping an entire data set and aggregating对整个数据集进行分组并聚合
【发布时间】:2014-09-19 08:51:04
【问题描述】:

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

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

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

有没有一种有效的方法来做到这一点?我想使用 apply 系列的功能,并且会 喜欢避免循环。

【问题讨论】:

    标签: r apply mean tapply


    【解决方案1】:

    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 即。

     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)
    

    然后使用lapplycolMeans 获取每个列表元素的列均值并使用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
    

    【讨论】:

    • 你能解释一下在 "(seq_len(.N)-1)%/%4 +1" 或 "mean(., na.rm=TRUE))) % 中使用 % >% " 我从来没有用过 "%" 并因此而感到不安。
    • 尤其是这一行"DT1
    • @user197393 1 不是必需的,正如我在解释中解释的那样。只是从1而不是0开始分组变量。您也可以使用函数gl。 IE。 as.numeric(gl(300, 4, 300)) 获取相同的分组变量。
    • @user197393 打错了,应该是as.numeric(gl(1200, 4, 1200))
    猜你喜欢
    • 1970-01-01
    • 2021-01-31
    • 2018-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-27
    • 2022-01-23
    相关资源
    最近更新 更多