【问题标题】:FOR loops giving no result or error in RFOR 循环在 R 中没有给出结果或错误
【发布时间】:2013-07-16 23:07:53
【问题描述】:

我正在运行以下代码:

 disc<-for (i in 1:33) {
 m=n[i]
 xbar<-sum(data[i,],na.rm=TRUE)/m 
 Sx <- sqrt(sum((data[i,]-xbar)^2,na.rm=TRUE)/(m-1))
 Sx
 i=i+1}

运行它:

 >disc
 NULL

为什么它给我NULL?

【问题讨论】:

  • 什么是ndata 是什么?
  • 当我不使用循环时,我必须一个接一个地运行它们。一个接一个地运行它们,我得到 Sx=4.5,3.5,....
  • 等等....你为什么要把for循环分配给一个变量?我不确定这是一个有效的任务,即使是这样,这也是一件很奇怪的事情。
  • 'n' 的长度为 44。dim(data) = 33 x 25
  • 是的,但是您为什么要尝试将for 循环分配给变量

标签: r if-statement


【解决方案1】:

这是来自for 的文档,可通过?`for` 访问:

“for”、“while”和“repeat”不可见地返回“NULL”。

也许您正在寻找以下方面的内容:

library(plyr)
disc <- llply(1:33, function(i) {
  m=n[i]
  xbar<-sum(data[i,],na.rm=TRUE)/m 
  Sx <- sqrt(sum((data[i,]-xbar)^2,na.rm=TRUE)/(m-1))
  Sx
})

存在其他变体——llply 中的ll 代表“列出,列出”。也许您想要的最终结果是一个数据框或一个数组——存在适当的函数。

上面的代码是您的示例的简单转换。我们可以通过立即拆分 data 并忘记原本无用的计数变量 i (未经测试,因为您没有提供数据)来做得更好:

disc <- daply(cbind(data, n=n), .(), function(data.i) {
  m=data.i$n
  xbar<-sum(data.i,na.rm=TRUE)/m 
  sqrt(sum((data.i-xbar)^2,na.rm=TRUE)/(m-1))
})

有关更多信息,另请参阅the plyr website

相关(如果不重复):R - How to turn a loop to a function in R

【讨论】:

  • 啊,对不起。应该意识到你不会把它留在那里。
  • @ayeshamalik:这只是因为 for 没有返回任何内容,正如文档所读的那样,我在答案的最顶部已经指出。
  • @krlmlr - 你写的第二个代码没有给出正确的答案。
  • @ayeshamalik:请问dput您的数据好吗?另见stackoverflow.com/q/5963269/946850
  • @krlmlr 你为什么在这里使用额外的包?我还看到您在另一条评论中给出了基本解决方案(有拼写错误)。
【解决方案2】:

krlmlr 的回答向您展示了如何修复您的代码,但用更抽象的术语解释了您的原始问题:for 循环允许您多次运行同一段代码,但它不存储运行该代码的结果为您编写代码 - 您必须自己完成。

您当前的代码实际上只为 for 循环的每次运行分配一个值 Sx。在下一次运行时,将一个新值放入 Sx 变量中,因此您将丢失所有以前的值。最后,您将得到 Sx 在最后一次循环中的值。

要保存 for 循环的结果,通常需要在执行过程中将它们添加到向量中,例如

# Create the empty results vector outside the loop
results = numeric(0)
for (i in 1:10) {
  current_result = 3 + i
  results = c(results, current_result)
}

【讨论】:

  • 我明白了。这真的很有帮助。在我的情况下,删除 Sx 可以完成这项工作。非常感谢!
  • @ayeshamalik:为了完整起见,plyr 相当于上面的代码:results &lt;- laply(10, function(i) 3+i)
  • @ayeshamalik:不,错误:results &lt;- laply(1:10, function(i) 3+i) 是正确的版本。
  • @Marius 你应该知道最好在循环之前预先分配!
【解决方案3】:

在 R 中 for 无法返回值。返回值的唯一方式是在函数内。所以这里的解决方案是将循环包装在一个函数中。例如:

getSx <- function(){
  Sx <- 0
  disc <- for (i in 1:33) {
    m=n[i]
    xbar <- sum(data[i,],na.rm=TRUE)/m 
    Sx <- sqrt(sum((data[i,]-xbar)^2,na.rm=TRUE)/(m-1))
  }
  Sx
}

那你叫它:

 getSx()

当然,您可以通过lapply 或通过向量化来避免使用for 的副作用但这是另一个问题:您可能应该给出一个可重现的示例并解释一下您尝试计算什么.

【讨论】:

    猜你喜欢
    • 2012-01-16
    • 2021-10-13
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多