【问题标题】:R function with FOR loop on a vector向量上带有 FOR 循环的 R 函数
【发布时间】:2015-04-04 05:54:40
【问题描述】:

当然是一个面部问题,抱歉。我一直在尝试 RTFM 和谷歌,但没有运气。

我正在尝试在 R 中创建一个愚蠢的函数,它以向量作为参数,用 for 循环遍历它,并对每个组件进行非常简单的添加。

func1 <- function(vector) {
  vr <- c() ### an empty vector 

  for (i in 1:length(vector)) { 
    vr <- vector[i]+i
  }
}

对我来说这看起来是正确的,但我总是得到一个 NULL 向量。为什么?

【问题讨论】:

  • 您可以删除vr &lt;- c()vr &lt;- vector[i]+i 并将vector[i] &lt;- vector[i] + 1 放入for 循环中。并且不要忘记在函数末尾返回对象(return(vector) 或只是 vector)。
  • function(v) {v + 1:length(v)} 还不够吗?您将在每个循环上覆盖 vr

标签: r function for-loop vector


【解决方案1】:

你可以像这样更有效地编写:

func1 <- function(vector){
    vector + seq_along(vector)
}

这样您就可以利用向量加法。

为了完整起见,让我们对这两种解决方案进行基准测试。这是一般的循环解决方案:

func2 <- function(vector) {
    vr <- c() ### an empty vector 

    for (i in 1:length(vector)) { 
        vr[i] <- vector[i]+i
    }
    vr
}

作为升级,还有就地解决方案

func3 <- function(vector) {    
    for (i in 1:length(vector)) { 
        vector[i] <- vector[i]+i
    }
    vector
}

使用microbenchmark,我们可以看到矢量化解决方案是迄今为止最有效的。

vec <- sample(100000, 10000)

library(microbenchmark)
microbenchmark(func1(vec), func3(vec), func2(vec))

Unit: microseconds
       expr       min        lq         mean    median       uq         max neval cld
 func1(vec)    29.998    36.984     44.78312    42.736    44.38     399.006   100  a 
 func3(vec) 12845.823 13666.432  14452.02863 14060.712 14708.53   25025.950   100  a 
 func2(vec) 84898.055 87354.750 110046.26659 88634.566 91193.38 1042819.269   100   b

【讨论】:

  • 好的,我明白了。这确实是一个:facepalm”:我认为它只会将一个完整的向量转储到 vr 中......是的,这是一个非常愚蠢的假设。让我忙了几个小时,哈哈。非常感谢 seq_along 函数和基准测试图书馆,确实很方便!
【解决方案2】:

您的代码很接近,但有两个问题。首先,除非使用return() 调用指定,否则R 中的函数会返回最后一个表达式。在您的函数中,这是 for 循环本身。但是 for 循环表达式本身不返回任何内容。

其次,最后一行没有在vr 上建立索引,因此您将用循环中的最后一个结果完全覆盖它。

因此,这段代码(我认为)会做你想做的事。但同意另一个答案,即有更简单的方法可以做到这一点。

func1 <- function(vector) {
  vr <- c() ### an empty vector 

  for (i in 1:length(vector)) { 
    vr[i] <- vector[i]+i
  }
  vr
}

这给出了这个输出:

> func1(c(1,2))
[1] 2 4

【讨论】:

  • 好答案。也就是说,这不是您通常在 R 中编写的方式。
猜你喜欢
  • 2017-08-28
  • 1970-01-01
  • 2021-07-05
  • 1970-01-01
  • 2012-12-21
  • 1970-01-01
  • 1970-01-01
  • 2016-12-07
  • 1970-01-01
相关资源
最近更新 更多