R:有没有一种简单的方法可以让ave()对矩阵起作用?

R:有没有一种简单的方法可以让ave()对矩阵起作用?,r,matrix,tapply,R,Matrix,Tapply,很抱歉,如果这看起来很琐碎,但在互联网上搜索了一段时间后,我找不到解决方案 我有一个矩阵和一个与列关联的因子向量。目标是分别获得所有因素的平均值,并保持原始矩阵结构。所以它可能类似于ave(),但在二维数组上工作 下面是一个粗略的演示: (mat <- rbind(1:5,6:10,11:15)) [,1] [,2] [,3] [,4] [,5] [1,] 1 2 3 4 5 [2,] 6 7 8 9 10 [3,]

很抱歉,如果这看起来很琐碎,但在互联网上搜索了一段时间后,我找不到解决方案

我有一个矩阵和一个与列关联的因子向量。目标是分别获得所有因素的平均值,并保持原始矩阵结构。所以它可能类似于ave(),但在二维数组上工作

下面是一个粗略的演示:

(mat <- rbind(1:5,6:10,11:15))
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    4    5
[2,]    6    7    8    9   10
[3,]   11   12   13   14   15

groups <- c(1,1,1,2,2)

mat[,groups==1] <- rowMeans(mat[,groups==1]) # I am asking about this part
mat[,groups==2] <- rowMeans(mat[,groups==2]) # ...

mat
     [,1] [,2] [,3] [,4] [,5]
[1,]    2    2    2  4.5  4.5
[2,]    7    7    7  9.5  9.5
[3,]   12   12   12 14.5 14.5
(mat1)假设您希望用该行的平均值替换每行的每个元素,请尝试此操作,其中
m
是您的矩阵:

ave(m, row(m))
如果这不是你想要的,请提供一个完整的例子,包括输入和输出

2)对于更新的问题,请尝试以下方法:

t(ave(t(m), group, t(row(m))))
或此等效变化:

ave(m, matrix(group, nrow(m), ncol(m), byrow = TRUE), row(m))
也许是这样:

mat.list  <- Map(matrix, split(mat, groups[col(mat)]), nrow = nrow(mat))
mean.list <- Map(rowMeans, mat.list)
do.call(cbind, mean.list[groups])

mat.list如果有一个优化的函数,比如rowGroupMeans,那就太好了,但我不知道有这样的事情

我的解决方案是使用rowsum,如下所示:

means <- rowsum(t(mat), groups)/tabulate(groups)
t(means)[, groups]

      1  1  1    2    2
[1,]  2  2  2  4.5  4.5
[2,]  7  7  7  9.5  9.5
[3,] 12 12 12 14.5 14.5

意味着我觉得第二个例子很接近。但它不能在我手中重现想要的结果。i、 e.我得到mat[2,]:(6.07.57.59.010.0)。应该是(79.59.5)有趣的方法。今天从你那里学到了一些东西。(不知道行()或列())。但是这有一个速度问题。这就像rowMeans(mat)和apply(mat,1,means)一样。rowMeans的速度要快得多,当矩阵行数达到数百万时,它就开始起作用了(请注意原始问题)。在大多数情况下,可读性比速度更重要。我很高兴接受你的答案。这是正确的,给了我一些新的想法。不过我觉得在这种情况下for循环更容易理解:)我真的认为我缺少了一些基本的单字函数。谢谢你的回复。您的解决方案对于rowMeans来说是最优雅、最快速的。然而,我以“rowMeans”为例(可能还不清楚),目标是实现完整的ave()类型方法。也就是说,我希望最终能够指定其他类型的函数(如rowMedians)。也许我会自己写一些包装。这里所有的答案都给了我一些想法。再次感谢你。
means <- rowsum(t(mat), groups)/tabulate(groups)
t(means)[, groups]

      1  1  1    2    2
[1,]  2  2  2  4.5  4.5
[2,]  7  7  7  9.5  9.5
[3,] 12 12 12 14.5 14.5
mat <- matrix(1:100e6, ncol = 100)
groups <- rep(1:10, each = 10)

## Map solution
for (i in 1:3){
    print(system.time({
        mat.list  <- Map(matrix, split(mat, groups[col(mat)]), nrow = nrow(mat))
        mean.list <- Map(rowMeans, mat.list)
        ans1 <- do.call(cbind, mean.list[groups])
    }))
}

   user  system elapsed 
   8.20    1.26    9.66 
   user  system elapsed 
  11.84    1.94   13.90 
   user  system elapsed 
  10.70    1.89   12.79

## rowsum solution
for (i in 1:3){
    print(system.time({
        means <- rowsum(t(mat), groups)/tabulate(groups)
        ans2 <- t(means)[,groups]
    }))
}

   user  system elapsed 
   1.56    0.22    1.78 
   user  system elapsed 
   1.48    0.27    1.74 
   user  system elapsed 
   1.57    0.14    1.72