【问题标题】:Using "apply" to apply a function to a matrix where parameters are column-specific使用“应用”将函数应用于参数是特定于列的矩阵
【发布时间】:2015-07-27 17:07:21
【问题描述】:

我试图通过使用apply 将用户定义的函数应用于矩阵来避免使用循环。我遇到的问题是我的函数使用了其他参数,并且它们对于矩阵的每一列都不同。下面是一个玩具示例。

假设我有以下功能:

foo <- function(x, a, b, c) return( (a*x + b)^c )

我想将其应用于矩阵bar,每列使用abc 的不同值。

bar <- matrix(1:15, ncol = 3)
a <- 4:6
b <- 3:1
c <- 1:3

在这种情况下,对于bar 的第一列,然后是a=4b=3c=1。我试过了,

apply(bar, 2, foo, a=a, b=b, c=c)

但这显然是不正确的,因为每一列都会依次使用所有参数,然后再返回到第一个参数。有什么建议吗?

【问题讨论】:

    标签: r apply


    【解决方案1】:

    我猜你可以只转置矩阵并使用矢量化:

    t(foo(t(bar),a,b,c))
    

    这应该适用于每个矢量化foo

    【讨论】:

      【解决方案2】:

      我完全不明白你为什么要为函数烦恼:

      > a <- matrix(4:6,nrow = 5,ncol = 3,byrow = TRUE)
      > b <- matrix(3:1,nrow = 5,ncol = 3,byrow = TRUE)
      > c <- matrix(1:3,nrow = 5,ncol = 3,byrow = TRUE)
      > (a*bar + b)^c
           [,1] [,2]   [,3]
      [1,]    7 1024 300763
      [2,]   11 1369 389017
      [3,]   15 1764 493039
      [4,]   19 2209 614125
      [5,]   23 2704 753571
      

      【讨论】:

      • @akrun 啊,我错过了你的答案。
      • 没关系。反正我也猜不到
      • @akrun 我实际上认为您对col 的使用要好得多。
      • 我认为rep 可能比回收和col 快​​一点
      • @joran 我上面给出的代码只是一个玩具示例。真正的问题是使用了一个由其他人在 R 包中定义的更复杂的函数——特别是 ReacTran 包中的 tran.1D
      【解决方案3】:

      您可以使用sweep;通常这是为了从每一列中减去平均值,但您可以传入一个索引来获得跨 a、b 和 c 的并行索引:

      > sweep(bar, 2, seq_along(a), function(x,i) foo(x, a[i], b[i], c[i]), FALSE)
           [,1] [,2]   [,3]
      [1,]    7 1024 300763
      [2,]   11 1369 389017
      [3,]   15 1764 493039
      [4,]   19 2209 614125
      [5,]   23 2704 753571
      
      【解决方案4】:

      我们可以通过'column' (col(bar)) split 'bar' 和mapply 我们可以将'foo' 应用到对应的'a'、'b'、'c' 值到每一列“酒吧”的

      mapply(foo, split(bar, col(bar)), a, b, c)
      

      或者不使用apply

      ind <- col(bar)
      (a[ind]*bar +b[ind])^c[ind]
      

      【讨论】:

      • 你也可以用split代替as.data.frame
      • @nicola 是的,我想把它保存在matrix
      • 我已经对第一个投了赞成票,现在希望能够为异常优雅的编辑添加投票。
      【解决方案5】:

      您可以将参数放入向量中:

      newbar <- rbind(a,b,c,bar)
      newfoo <- function(z){x <- z[-(1:3)]; (z[1]*x+z[2])^z[3]}
      apply(newbar,2,newfoo)
      

      给了

      [,1] [,2]   [,3]
          7 1024 300763
         11 1369 389017
         15 1764 493039
         19 2209 614125
         23 2704 753571
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-08
        • 2020-01-16
        • 1970-01-01
        • 2018-10-09
        相关资源
        最近更新 更多