【问题标题】:how to avoid this loop in R (rapply ? lapply ?)如何避免R中的这个循环(rapply?lapply?)
【发布时间】:2014-06-27 12:19:48
【问题描述】:

我试图用一个没有任何成功的简单命令替换这个循环(lapply ? rapply ? mapply ?)。也许在 R 中确实需要循环是一种罕见的情况?

n <- 10
x <- vector(mode="numeric", length=n)

for(i in 2:n) {
    x[i] <- x[i-1]+runif(1)
}

我的问题表述不当。这些回答帮助我理解了我真正需要的是把一个向量的值访问到一个函数中。使用对于任何函数“f”来说都很简单的循环,我们可以计算出:

x <- c(1,2,3,4)
for(i in 2:4) {
    x[i] <- f(x[i-1])
}

也许唯一的方法是全局变量?

【问题讨论】:

标签: r loops lapply mapply


【解决方案1】:

对于您的确切问题,您根本不需要 apply 函数,因为您可以使用 cumsum 对其进行矢量化:

您的代码:

n <- 10
x <- vector(mode="numeric", length=n)

set.seed(1)
for(i in 2:n) {
  x[i] <- x[i-1]+runif(1)
}
x
[1] 0.0000000 0.2655087 0.6376326 1.2104859 2.1186937 2.3203756 3.2187653 4.1634406 4.8242384
[10] 5.4533524

我的代码:

set.seed(1)
c(0, cumsum(runif(n-1)))
 [1] 0.0000000 0.2655087 0.6376326 1.2104859 2.1186937 2.3203756 3.2187653 4.1634406 4.8242384
[10] 5.4533524

【讨论】:

  • 谢谢,是的 cumsum 是完美的答案,对不起,我的示例代码很简单,我需要添加 x[i] = x[i-1]+afunction(x[i -1])...
  • @LeonEspinosa 在你的情况下afunction() 是什么?
  • 对不起,任何将作为参数 "x[i-1]" 的函数,例如 x[i] = x[i-1]+x[i-1]^2
  • @LeonEspinosa 您已经对原始帖子获得了四个很好的答案,并且您对每个问题都发表了评论,认为它们对您不利,因为您的实际问题并未在原始帖子中得到体现.请编辑您的原始帖子以代表您真正需要的内容。
【解决方案2】:

您可以使用cumsum。因此,只需将零添加到随机变量向量的累积总和

n <- 10
x <- vector(mode="numeric", length=n)
rData <- runif(9)
for(i in 2:n) {
  x[i] <- x[i-1]+rData[i-1]
}

identical(c(0, cumsum(rData)), x)

> identical(c(0, cumsum(rData)), x)
[1] TRUE

【讨论】:

  • 谢谢!我的代码示例太简单了......“runif”部分将被更复杂的函数替换,该函数取决于 x[i-1] 值
【解决方案3】:

你可以像 sapply 一样使用

c(x[1],(sapply(x,function(a){a+runif(1)})[-length(x)]))

【讨论】:

  • 谢谢,这似乎不是重现循环解决方案,循环的结果是一个递增的序列,分别是 x[i] = x[i-1] + something。这个 sapply 命令产生一个带有偏移值(= 初始 x 值)的随机集。如果我是正确的 lapply 和 sapply 在内存中构建结果值以产生“整体”结果,所以我无法访问中间值作为 x[i-1]
【解决方案4】:

实现此目的的另一种方法是使用Reduce

f <- function(a, b) a + runif(1)  
x <- Reduce(f, x, accumulate = TRUE)

(只是建议将此作为一种通用的替代方案;其他答案中的cumsum 方式更快)

【讨论】:

  • 谢谢,是的,它完美运行。但是函数 f 可以访问 x 的每个值吗?例如 f
  • 您在寻找Reduce(function(a, b) a ^ 2 + b, 1:10, accumulate = T)吗?基本上,您必须将b 视为将值x[i]a 的值从应用于x 的先前条目的函数中迭代。因此无需致电length(a),只需a 即可。 f 是两个“标量”(或长度为 1 的向量,如果您愿意,使用 R 语言)的函数。
  • 关于f 是否可以访问x 的所有值的问题,在这种情况下答案是否定的,因为这不是Reduce 的工作方式。 Reduce 采用 2 个参数的函数并将其迭代地应用于向量。如果您需要访问x 的所有单个条目,您需要想出另一种方法(可能使用Map,但仍然不确定您的功能是什么样的以及您到底想要做什么)。
  • 是的,恐怕我需要的只是访问将要应用的函数中的向量值。也许全局变量可能是一种解决方法
  • 我认为在大多数情况下使用全局变量并不是一个好主意。所以你有一个函数f和一个长度为N的向量x,你想获得一个向量(f(x[1]), f(c(x[1], x[2])), ..., f(c(x[1],...,x[N])),对吧?你写一个函数g &lt;- function(n, v) f(v[1:n])然后使用lapply(1:N, g, v = x)怎么样?不过,这可能不是最有效的方法,我认为如果您更准确地了解 f 的外观,那么您可以加快速度(例如使用 cumsum,正如其他人为您提供的示例所建议的那样)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-29
  • 1970-01-01
  • 2021-08-10
  • 1970-01-01
  • 1970-01-01
  • 2011-03-20
相关资源
最近更新 更多