【问题标题】:R: Storing Loop Result in a VectorR:将循环结果存储在向量中
【发布时间】:2021-01-03 13:18:29
【问题描述】:

我正在尝试运行一个将结果存储在向量中的循环。但我还需要在预定向量上增加计数器,以使存储的计算正常运行。我被困在两个部分:(1)增加计数器,(2)将循环结果存储在向量中。

我是循环新手,所以请忍受下面最有可能不正确的语法;这是我正在使用的:

x <- c(.01,.05,.10,.20,.25) # observed defect rates
for(i in x) {
  j <- 1
  if(x < 1){
    atmost2[] <- dbinom(0,size=10,prob=x[[j]])+
    dbinom(1,size=10,prob=x[[j]])+
    dbinom(2,size=10,prob=x[[j]]) &&
      j <- j + 1
  }
}
atmost2

本质上,我想将结果存储在一个新向量 atmost2 中,每个连续循环通过增加 j 来遍历 x 中的向量值; j 应该增加以从 x 中的预定向量值更改 dbinom 中的 prob 参数。

有人可以帮忙吗?

【问题讨论】:

  • 代码的工作原理不清楚。因为j &lt;- 1 是一个常量,所以应该将它移到for 循环之外。不需要if(x &lt; 1) 语句,因为所有x 值都小于1。等式中的逻辑运算符&amp;&amp; 对我来说没有意义。此外,if 中的 j &lt;- j + 1 术语只会在循环中使用 j &lt;- 1 重新初始化为 1,如果您将其保留在那里。

标签: r loops for-loop vector indexing


【解决方案1】:

一些事情:

juljo 在循环之前初始化向量是正确的,他们做了一些其他的更正,但我认为他们的代码只有在你已经建立的情况下才有效:

j <- 1

否则,juljo 的代码就会中断。

此外,您的代码不需要“&&”即可工作。只需将 j

j <- 1
x <- c(.01,.05,.10,.20,.25) # observed defect rates
atmost2 <- as.numeric(1:length(x))  # this initializes the vector to a predetermined length which may help with very large loops
for(i in 1:length(x)) {
  
  if(x < 1){
    atmost2[i] <- dbinom(0,size=10,prob=x[j])+   # note that the double brackets are gone
      dbinom(1,size=10,prob=x[j])+
      dbinom(2,size=10,prob=x[j]) 
  }
  j <- j + 1  # I think you want j to increment outside the if statement
}
atmost2

此代码执行“某些操作”,但有一些警告,我不确定您要做什么。

您也可以跳过添加 dbinom 并改为:

j <- 1
x <- c(.01,.05,.10,.20,.25) # observed defect rates
atmost2 <- as.numeric(1:length(x))  # this initializes the vector to a predetermined length which may help with very large loops
for(i in 1:length(x)) {
  
  if(x < 1){
    atmost2[i] <- sum(dbinom( 0:2 , size=10,prob=x[j]))  #dbinom will give a vector that can be summed
  }
  j <- j + 1  # I think you want j to increment outside the if statement
}
atmost2

但我认为使用 j 迭代器可能是其他编程语言的习惯。注意使用循环但没有 j 的相同输出:


x <- c(.01,.05,.10,.20,.25) # observed defect rates
atmost2 <- as.numeric(1:length(x))  # this initializes the vector to a predetermined length which may help with very large loops
for(i in 1:length(x)) {
  
  if(x < 1){
    atmost2[i] <- sum(dbinom(0:2,size=10,prob=x[i])) 
  }
  }
atmost2

这些都产生相同的输出:

> atmost2
[1] 0.9998862 0.9884964 0.9298092 0.6777995 0.5255928

但我有后续问题:

atmost2 应该与 x 长度相同吗?

您是否使用 x 中的值作为概率?那么,atmost2 是基于 x[i] 的值的 dbinom 概率之和?

它必须是一个循环吗? R 很好地使用了向量,因此 apply 函数可能会有所帮助。您可能会发现 lapply 在这里很有用。 ?apply 可能会让你开始 ?lapply 将给出其他应用函数的描述。

所以你的代码可能看起来像这样

x <- c(.01, .05, .10, .20, .25)
atmost2 <- as.numeric(1:length(x)) 

atmost2 <- lapply(x, function(x) sum(dbinom( 0:2 , size = 10, prob = x)))

atmost2   # this is a list, not a vector

lapply 函数如下所示:

应用于列表中的项目,'x',一个函数。

在这种情况下,该函数是一个匿名函数“sum(dbinom....)”

因此,将函数 sum(dbinom...) 应用于 x 的每个值并返回一个列表。

基本上,它会为您完成循环。并且通常比 for 循环(在 R 中)快几倍。

如果您需要 atmost2 不是列表而是向量,您可以:

unlist(atmost2)

>   unlist(atmost2)
[1] 0.9998862 0.9884964 0.9298092 0.6777995 0.5255928

根据Rui的提醒编辑

使用 sapply,其他一切都一样,但输出确实是一个向量。

x <- c(.01, .05, .10, .20, .25)
atmost2 <- as.numeric(1:length(x)) 

atmost2 <- sapply(x, function(x) sum(dbinom( 0:2 , size = 10, prob = x)))

atmost2   # this is a vector

【讨论】:

  • 如果您使用sapply 而不是lapply,则不需要unlist。赞成,顺便说一句。
  • 当然。我假设 OP 是新的,根据我自己的经验, lapply 更容易理解。
  • Brian 是对的,我的答案必须进行编辑,并且 j 需要替换为 i。显然sapply 解决这个问题的方式更好。
  • 感谢您的回复!所有人都对理解 R 中的功能非常有帮助(你可能已经注意到我很绿)。我对您的问题的跟进: atmost2 应该与 x 的长度相同吗? --> atmost2 应该和 x 的长度相同 你是否使用 x 中的值作为概率? --> 是 那么,atmost2 是基于 x[i] 值的 dbinom 概率之和? --> 是的;使用 sum 函数和从 0:2 开始排序的合并是 rad!它必须是一个循环吗? --> 没有;使用 lapply 和 sapply 的解决方案非常适合简洁和合并
【解决方案2】:

这样调用元素怎么样:

x <- c(.01,.05,.10,.20,.25) # observed defect rates
atmost2 <- numeric() # Initialize vector before filling it in the loop
for(i in 1:length(x)) {
  if(x[i] < 1){
    atmost2[i] <- dbinom(0,size=10,prob=x[i])+
      dbinom(1,size=10,prob=x[i])+
      dbinom(2,size=10,prob=x[i])
  }
}
atmost2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-24
    • 1970-01-01
    • 2013-03-04
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多