如何创建一个循环

5
你能解释一下R语言中"循环"的结构/思想吗?我不知道该如何开始做这个作业。我已经能够使用指数分布来创建需要的内容了。
> rexp(n=200, rate=0.5) 

现在我需要创建2,000个此rexp样本并计算每个样本的平均值。然后我需要计算这2,000个样本平均值的平均值和方差。我知道如何找到简单分布的平均值和方差(例如:mean(rexp)var(rexp)),所以我的主要问题是理解循环的概念并将其付诸实践。

所以我开始输入:

> rexp(n=200,rate=0.5)

然后我给这个指数分布取了个名字:

> exdi = rexp(n=200,rate=0.5)

根据一个有关求和的例子,我输入了

>y.exdi=vector(length=2000)
>for(i in 1:2000){y.exdi[ i ]=mean(exdi)}
工作空间对此没有响应,因此我命名了该函数并尝试了这个:
>Twothou = for(i in 1:2000){y.exdi[ i ]=mean(exdi)}
>mean(Twothou)

但是我收到了以下错误信息:
[1] NA
Warning message:
In mean.default(Twothou) : argument is not numeric or logical: returning NA

我应该做些什么不同的事情呢?

5个回答

6
您刚刚创建了一个非常好的向量,包含了2000个相同值的元素,这些元素是基于仅一次指数分布样本平均值计算而来的。通过检查控制台中的y.exdi进行验证。
如果您想使用循环解决此问题,那么您应该在每次迭代中创建新的样本。您可以使用例如应用于1:2000sapplyfor循环的包装器)轻松实现这一点。
sapply(1:2000, function(x) mean(rexp(n = 200, rate = 0.5)))

或者直接调用例如replicate(旨在用于这种情况):

replicate(2000, mean(rexp(n = 200, rate = 0.5)))

2
+1 表示“复制”。我不建议使用sapply方法,因为编写一个忽略其参数的函数是丑陋的。 - flodel
忽略 replicate 包装了 sapply 这一事实。 :) - Joshua Ulrich

3

我认为你应该将随机数生成器 rexp 放在 你的 for 循环内:

y.exdi=vector(length=2000)
for(i in 1:2000){
    y.exdi[ i ]=mean(rexp(n=200,rate=0.5))
}

否则,对于每个i,您只需计算在循环外定义的固定向量的平均值,而不是每次索引i增加时生成新的向量。有了上面的代码,您可以使用mean(y.exdi)来计算平均值,这将给出2000个“平均值”的平均值。

2

您需要在循环中创建样本分布。请尝试以下内容:

> set.seed(1)
> y.exdi=vector(length=2000)
> for(i in 1:2000){
+ exdi = rexp(n=200,rate=0.5)
+ y.exdi[ i ]=mean(exdi)
+ }
> mean(y.exdi)
[1] 2.001149
> var(y.exdi)
[1] 0.01987367

如果你的回答和比你快一秒钟的人没有太大的区别,请考虑删除你的回答。 - flodel

2

由于需要生成2000次样本,因此样本生成必须在循环中进行。

set.seed(1)
y.exdi <- vector(length=2000, "numeric")
for (i in 1:2000)
{
    y.exdi[i] <- mean(rexp(200, 0.5))
}

问题还出现在命令中。
   exdi = rexp(n=200,rate=0.5)

代码中的exdi实际上是被赋值为一个包含200个指数分布随机生成值的数值向量,并不是定义了一个函数。事实上,你不需要重新定义一个函数,每次只需调用rexp即可。

R语言还提供了这些操作的快捷方式。你可以用一行代码得到2000个均值。

sapply(1:2000, function(x) { mean(rexp(200, 0.5)) })

如果你的答案和比你快一秒钟回答的人的并没有太大区别,请考虑删除你的回答。 - flodel

0

这里有两种解决方案。第一种不需要创建两次样本,但匿名函数及其返回的列表是奇怪的。第二种更干净,您可以获得列名,但不再将均值与同一样本的方差绑定。

library(plyr)

ldply(1:2000, function(x) {d <- rexp(n = 200, rate = 0.5); c(mean(d), var(d))})

ddply(data.frame(x = 1:2000), .(x), summarize, 
  mean = mean(rexp(n = 200, rate = 0.5)), var = var(rexp(n = 200, rate = 0.5)))

你的解决方案将值放入y.exdi列表中。如果在构建时查看其内容,它将充满布尔FALSE值。循环后,您可以重新检查它,并查看它的元素是否具有平均值。以下是两种同样有效的方法,以完成您尝试使用循环完成的事情,并进行了一些清理。

y.exdi <- NULL
for(i in 1:2000) y.exdi[i] <- mean(rexp(n = 200, rate = 0.5))

y.exdi <- vector(length = 2000, mode = "numeric")
for(i in seq(y.exdi)) y.exdi[i] <- mean(rexp(n = 200, rate = 0.5))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接