【问题标题】:Apply function too slow in r在 r 中应用函数太慢
【发布时间】:2015-05-21 10:43:34
【问题描述】:

我必须为很多物种计算每行的特定公式。该公式是丰度值与数据框最后一行中存在的值之间的乘积。然后,将所有这些产品相加。

我当前的脚本包括使用一个看起来与我开始使用的 for 循环一样慢的应用函数。 我使用名为az 的简单df 简化了以下脚本中的问题:

az=data.frame(c(1,2,10),c(2,4,20),c(3,6,30))
colnames(az)=c("a","b","c")


# Initial for loop
prov=0 # prov for provisional number
    for (i in 1:nrow(az)){
            for (j in 1:ncol(az)){
                   prov=prov+az[i,j]*az[nrow(az),j]
            }
        print(prov)
        prov=0
        }

# Apply solution
apply(az[,], 1, function(x) {sum(x*az[nrow(az),], na.rm=TRUE)})

这两种解决方案都有效,但速度很慢(使用我原来的 df),我必须对大量物种重复该操作。 因此,我想知道是否有人有更有效的解决方案,也许使用矢量化表达式。

亲切的问候。

【问题讨论】:

    标签: r loops apply


    【解决方案1】:

    试试

      rowSums(az*unlist(az[nrow(az),])[col(az)], na.rm=TRUE)
    

    或者稍微快一点的选择是使用rep

      rowSums(az*rep(unlist(az[nrow(az),]),each=ncol(az)), na.rm=TRUE)
    

    【讨论】:

    • 非常感谢您的回答。然而,矩阵代数版本要快一些。
    • @user3443183 没问题。我也会矩阵代数
    【解决方案2】:

    最快的解决方案可能是矩阵代数:

    apply(az[,], 1, function(x) {sum(x*az[nrow(az),], na.rm=TRUE)})
    #[1]  140  280 1400
    
    m <- as.matrix(az)
    m[is.na(m)] <- 0 #remove NA from sums
    as.vector(m %*% m[nrow(m),])
    #[1]  140  280 1400
    

    【讨论】:

    • tcrossprod 可能会快一点 as.vector(tcrossprod( m[nrow(m),],m))
    • @akrun 一般来说是的,但我不太确定它是否在一个因素只是一个向量的特定情况下提供好处。
    • 我为你准备了最难的一个(但我无法编辑我的初始帖子)。我不必在初始 for 循环中执行 prov=prov+az[i,j]*az[nrow(az),j],而是必须使用 m[] 执行 prov=prov+az[i,j]*(az[nrow(az),j-m[])^2],这是我们在初始帖子中每行得到的结果。它实际上是一个方差计算(第一个对应于平均值)。我够清楚了吗?
    • 请提出一个新问题。
    • 好的,这里是链接:[stackoverflow.com/questions/29128432/…
    猜你喜欢
    • 2013-11-13
    • 2022-01-11
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    • 1970-01-01
    • 2016-07-20
    相关资源
    最近更新 更多