2013-02-25 65 views
1

我目前正在学习R,并且我试图改变for循环来使用apply。 上下文是一个带有2个变量的父框架(以英寸为单位)和子框架(以英寸为单位)的数据框浮雕。我想从中反复取样并获得线性模型(使用lm)并将结果保存到向量中。重新设计一个for循环使用适用于R

library(UsingR) 
sampleLm <- vector(100,mode="list") 
for(i in 1:100) { 
    sampleGalton <- galton[sample(1:length(galton$child),size=50,replace=F),] 
    sampleLm[[i]] <- lm(sampleGalton$child ~ sampleGalton$parent) 
} 

我尝试这样做:

sampleLm <- vector(100,mode="list") 
sapply(samples, function(x) { 
    sampleGalton <- galton[sample(1:length(galton$child),size=50,replace=F),] 
    x <- lm(sampleGalton$child ~ sampleGalton$parent) 
}) 

样品是从父母给孩子高度的高尔顿高度所采取的代码。 你可以在UsingR包中获取这些数据。这样你会得到游戏。但真的可能是任何事情。只是一些常规的数据框。

但虽然它正确执行,sampleLm矢量未更新,并且包含所有None。我觉得这是正常的,因为我从R文档中找到了“无副作用”规则。

必须有一种方法来重新表达这个,所以for被替换为apply。问题是如何?

+0

什么是'samples'?请使您的代码具有可重现性。 – 2013-02-25 16:26:33

+0

为什么你会期望第二个版本修改sampleLm?我没有看到任何会导致sapply语句修改sampleLm的内容。 – Dason 2013-02-25 16:27:12

+0

与'apply'系列函数不同,您不需要创建输出变量并像在for循环中那样填充它。相反,将'sapply'的输出分配给它:'sampleLm < - sapply(...)'。 – Justin 2013-02-25 16:27:59

回答

4

最简单的方法在这里是replicate

sampleLm <- replicate(100, lm(child ~ parent, data = galton, 
           subset = sample(seq(nrow(galton)), size = 50)), 
         simplify = FALSE) 
+0

非常感谢斯文!这正是我所希望的那种答案。 – 2013-03-01 23:57:07

2

使用* apply系列时,不需要预先分配sampleLm。你只需要编写你想要运行的函数,这样它就可以转化感兴趣的结果,然后将最终结果存储在一个变量中。

sampleLm <- sapply(samples, function(x) { 
    sampleGalton <- galton[sample(1:length(galton$child),size=50,replace=F),] 
    lm(sampleGalton$child ~ sampleGalton$parent) 
})