【问题标题】:Dividing columns by colSums in R在R中将列除以colSums
【发布时间】:2021-12-29 04:01:26
【问题描述】:

我正在尝试缩放矩阵中的值,以便每列加起来为一。我试过了:

m = matrix(c(1:9),nrow=3, ncol=3, byrow=T)
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9

colSums(m)
12 15 18

m = m/colSums(m)
          [,1]      [,2] [,3]
[1,] 0.08333333 0.1666667 0.25
[2,] 0.26666667 0.3333333 0.40
[3,] 0.38888889 0.4444444 0.50

colSums(m)
[1] 0.7388889 0.9444444 1.1500000

显然这不起作用。 然后我尝试了这个:

m = m/matrix(rep(colSums(m),3), nrow=3, ncol=3, byrow=T)
          [,1]      [,2]      [,3]
[1,] 0.08333333 0.1333333 0.1666667
[2,] 0.33333333 0.3333333 0.3333333
[3,] 0.58333333 0.5333333 0.5000000

 m = colSums(m)
[1] 1 1 1

所以这行得通,但感觉就像我在这里遗漏了一些东西。这不可能是例行公事。我敢肯定我在这里是愚蠢的。 您可以提供的任何帮助将不胜感激 干杯, 戴维

【问题讨论】:

    标签: r


    【解决方案1】:

    ?sweep,例如:

    > sweep(m,2,colSums(m),`/`)
               [,1]      [,2]      [,3]
    [1,] 0.08333333 0.1333333 0.1666667
    [2,] 0.33333333 0.3333333 0.3333333
    [3,] 0.58333333 0.5333333 0.5000000
    

    或者您可以转置矩阵,然后colSums(m) 被正确回收。之后不要忘记再次转置,像这样:

    > t(t(m)/colSums(m))
               [,1]      [,2]      [,3]
    [1,] 0.08333333 0.1333333 0.1666667
    [2,] 0.33333333 0.3333333 0.3333333
    [3,] 0.58333333 0.5333333 0.5000000
    

    或者你使用函数prop.table()做的基本一样:

    > prop.table(m,2)
               [,1]      [,2]      [,3]
    [1,] 0.08333333 0.1333333 0.1666667
    [2,] 0.33333333 0.3333333 0.3333333
    [3,] 0.58333333 0.5333333 0.5000000
    

    时差很小。 sweep() 函数和 t() 技巧是最灵活的解决方案,prop.table() 仅适用于这种特殊情况

    【讨论】:

      【解决方案2】:

      按照惯例,Joris 有一个很好的答案。想到的另外两个:

      #Essentially your answer
      f1 <- function() m / rep(colSums(m), each = nrow(m))
      #Two calls to transpose
      f2 <- function() t(t(m) / colSums(m))
      #Joris
      f3 <- function() sweep(m,2,colSums(m),`/`)
      

      Joris 的回答是我机器上最快的:

      > m <- matrix(rnorm(1e7), ncol = 10000)
      > library(rbenchmark)
      > benchmark(f1,f2,f3, replications=1e5, order = "relative")
        test replications elapsed relative user.self sys.self user.child sys.child
      3   f3       100000   0.386   1.0000     0.385    0.001          0         0
      1   f1       100000   0.421   1.0907     0.382    0.002          0         0
      2   f2       100000   0.465   1.2047     0.386    0.003          0         0
      

      【讨论】:

      • 好像你的帖子和我的编辑互相通过了。谢谢你的赞美。
      • 除非你正在处理一个庞大的数据集,否则我喜欢 sweep 的表现力......只是为了可爱,exp(scale(log(m),center=TRUE,scale=FALSE)) 怎么样(由于很多原因不是一个好主意!)
      • scale(m, center=FALSE, scale=colSums(m))
      【解决方案3】:

      当然晚了,但我只是用了

      adorn_percentages(table.with.value, denominator = "col").
      

      更多信息请点击以下链接:https://rdrr.io/cran/janitor/man/adorn_percentages.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多