【问题标题】:Taking row means based on a partition of the columns基于列的分区取行均值
【发布时间】:2012-03-31 11:03:42
【问题描述】:

我有一个矩阵mat,想根据分组变量gp 计算列的平均值。

mat<-embed(1:5000,1461)
gp<-c(rep(1:365,each=4),366)

为此,我使用以下方法

colavg<-t(aggregate(t(mat),list(gp),mean))

但这比我预期的要长得多。

关于让代码运行得更快有什么建议吗?

【问题讨论】:

  • 加速R代码的第一步:stackoverflow.com/a/8474941/636656
  • 特别是 data.table 在这里可能会有所帮助。
  • @gsk3 感谢您的指点。我不熟悉data.table,但会做一些阅读。

标签: r matrix


【解决方案1】:

这是一个快速算法,我在代码中注释了。

system.time({

# create a list of column indices per group
gp.list    <- split(seq_len(ncol(mat)), gp)

# for each group, compute the row means
means.list <- lapply(gp.list, function(cols)rowMeans(mat[,cols, drop = FALSE]))

# paste everything together
colavg     <- do.call(cbind, means.list)

})
#    user  system elapsed 
#    0.08    0.00    0.08 

【讨论】:

    【解决方案2】:

    您可以使用 apply 函数,例如来自优秀的 plyr 包:

    # Create data
    mat<-embed(1:5000,1461)
    gp<-c(rep(1:365,each=4),366)
    
    # Your code
    system.time(colavg<-t(aggregate(t(mat),list(gp),mean)))
    
    library(plyr)
    # Put all data in a data frame
    df <- data.frame(t(mat))
    df$gp <- gp
    
    # Using an apply function
    system.time(colavg2 <- t(daply(df, .(gp), colMeans)))
    

    输出:

    > # Your code
    > system.time(colavg<-t(aggregate(t(mat),list(gp),mean)))
       user  system elapsed 
     134.21    1.64  139.00 
    
    > # Using an apply function
    > system.time(colavg2 <- t(daply(df, .(gp), colMeans)))
       user  system elapsed 
      52.78    0.06   53.23 
    

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 2020-06-26
      • 2016-12-07
      • 2021-05-11
      • 1970-01-01
      • 1970-01-01
      • 2021-08-25
      相关资源
      最近更新 更多