【问题标题】:Add column means and row means to a matrix in r将列均值和行均值添加到 r 中的矩阵
【发布时间】:2016-09-26 10:40:39
【问题描述】:

我有一个新手问题:

  Example of a dataset: 
  dat = matrix(1:6,3,2) #create a dataset
 #     [,1] [,2]
#[1,]    1    4
#[2,]    2    5
#[3,]    3    6

  rmean = rowMeans(dat)  # calculate the row means of dat
 #[1] 2.5 3.5 4.5
  cmean = colMeans(dat)  # calculate the colum means of dat
 #[1] 2 5

我想要一个如下的矩阵:

      [,1] [,2]
[1,]   5.5  11.5
[2,]   7.5  13.5
[3,]   9.5  15.5

第一行计算如下:

  1+rowmeans(2.5) + colmeans(2) = 5.5
  4+rowmeans(2.5) + colmeans(5) = 11.5

这是我尝试过的:

  newdat = matrix(NA, 3,2)
  for (row in 1:nrow(dat))
    for (col in 1:ncol(dat)) {
    rmean = rowMeans(dat)
    cmean = colMeans(dat)
    newdat[row,col] = dat[row,] + rmean[row] + cmean[col]
  }

任何帮助将不胜感激,请更正我的 for 循环。

【问题讨论】:

  • 我看这里没有减法,尽管有标题
  • 另一个相当愚蠢的选择:dat + ave(dat, col(dat)) + ave(dat, row(dat))

标签: r for-loop matrix


【解决方案1】:

这可以简单地利用+ 逐个元素地对矩阵进行操作这一事实来完成,而无需使用for 循环或sweep。依靠回收来用列和行手段填充矩阵。

dat + matrix(rowMeans(dat),3,2) + matrix(colMeans(dat),3,2, byrow = T) 
##     [,1] [,2]
##[1,]  5.5 11.5
##[2,]  7.5 13.5
##[3,]  9.5 15.5

【讨论】:

    【解决方案2】:

    R中有很多处理矩阵的函数;这通常只是找到你想要的那个的问题。在这种情况下,sweep 就是你想要的:

    sweep(sweep(dat, 1, rowMeans(dat), `+`), 2, colMeans(dat), `+`)
    #      [,1] [,2]
    # [1,]  5.5 11.5
    # [2,]  7.5 13.5
    # [3,]  9.5 15.5
    
    • 第二个参数是边距,如apply,其中1为行,2为列;
    • 第三个是跨行/列操作的向量;和
    • 第四个是对它们执行的操作。您需要在 + 周围加上反引号才能将其作为名称传递。

    弄清楚如何安排这些功能可能会很痛苦,但一旦你这样做了,它们就会非常有用。遗憾的是,一些更复杂的帮助页面很难理解,但here's some useful reading 解释得更好。


    或者,您可以发挥一些创意并利用矢量回收:

    t(t(dat + rowMeans(dat)) + colMeans(dat))
    #      [,1] [,2]
    # [1,]  5.5 11.5
    # [2,]  7.5 13.5
    # [3,]  9.5 15.5
    

    【讨论】:

    • 对于“滥用回收”的方式,我会做dat + rowMeans(dat) + colMeans(dat)[col(dat)]
    • @alistaire 谢谢,但如果我必须使用循环(我知道在 R 中不建议这样做),我将如何改进我的 for 循环?我做错了什么你能解决吗?这纯粹是为了我自己的理解。谢谢
    • 首先,除非绝对必要,否则不要使用循环。也就是说,您缺少一些大括号,并且在分配时需要将dat 子集为rowcol。此外,您应该在循环之外计算行和列的平均值,因此您不会重复计算相同的东西。总而言之:rmean <- rowMeans(dat) ; cmean <- colMeans(dat) ; newdat <- matrix(NA, 3,2) ; for (row in 1:nrow(dat)){ for (col in 1:ncol(dat)) { newdat[row, col] = dat[row, col] + rmean[row] + cmean[col] }}
    【解决方案3】:

    不需要循环。 R 的优点是使用矩阵/向量运算来完成您想要实现的目标。

    dat = matrix(1:6,3,2) #create a dataset
    
    rmean = rowMeans(dat)
    cmean = colMeans(dat)
    
    newdat = dat + rmean 
    
    newdat = t(apply(newdat, 1, function(x) x + cmean))
    

    【讨论】:

    • 谢谢,但如果我必须使用循环(我知道在 R 中不建议这样做),我将如何改进我的 for 循环?我做错了什么。
    【解决方案4】:

    我们可以使用rowcol 函数进行复制

    dat+rowMeans(dat)[row(dat)] + colMeans(dat)[col(dat)]
    #     [,1] [,2]
    #[1,]  5.5 11.5
    #[2,]  7.5 13.5
    #[3,]  9.5 15.5
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-23
      • 2017-08-21
      • 2018-08-27
      • 1970-01-01
      • 2015-01-13
      • 2014-03-15
      相关资源
      最近更新 更多