2014-09-23 84 views
5

我试着在不同的数据集上运行anova,但并不知道如何去做。我goolged,发现这是有用的:http://www.ats.ucla.edu/stat/r/pages/looping_strings.htmr和anova一起替换

hsb2 <- read.csv("http://www.ats.ucla.edu/stat/data/hsb2.csv") 
names(hsb2) 
varlist <- names(hsb2)[8:11] 
models <- lapply(varlist, function(x) { 
lm(substitute(read ~ i, list(i = as.name(x))), data = hsb2) 
}) 

我的什么上面的代码所做的就是创建了一个函数LM(),它适用于varlist中的每一个变量,它在每个人的线性回归的理解。

于是我想到用AOV代替LM将工作对我来说是这样的:

aov(substitute(read ~ i, list(i = as.name(x))), data = hsb2) 

不过,我得到这个错误:

Error in terms.default(formula, "Error", data = data) : 
no terms component nor attribute 

我没有哪里的错误来自主意。请帮忙!

+3

这是一个相当复杂的方式来包含他们建议的变量。我可能会这样做:'lm(as.formula(paste(“read〜”,x)),data = hsb2)@ – thelatemail 2014-09-23 05:25:22

+0

@RichardScriven:你想知道这是否是一个“永恒的九月”的例子本科生的谦虚能干?) – 2014-09-23 05:55:01

+1

@BonddedDust我希望我仍然是本科生.. – olala 2014-09-23 13:38:01

回答

5

的问题是,substitute()返回表达式,不是一个公式。我认为@ thelatemail的建议

lm(as.formula(paste("read ~",x)), data = hsb2) 

是一个很好的解决方法。另外,您可以评估表达

models <- lapply(varlist, function(x) { 
    aov(eval(substitute(read ~ i, list(i = as.name(x)))), data = hsb2) 
}) 

得到公式我想这取决于你想以后用的型号列表做什么。做

models <- lapply(varlist, function(x) { 
    eval(bquote(aov(read ~ .(as.name(x)), data = hsb2))) 
}) 

给出了一个“清洁”call属性为每个结果。

+0

你不应该同时需要'bquote'和'substitute' - 选择一个!例如'eval(bquote(aov(read〜。(as.name(x)),data = hsb2)))' – hadley 2014-09-23 17:25:44

+0

Thanks @hadley。不知道我为什么很傻。我已根据您的评论进行更新。 – MrFlick 2014-09-23 18:18:04

+0

“替代”或“bquote”都不会返回表达式。通常他们会回电话。 – 2014-09-23 22:03:54

5

这应该这样做。 varlist向量将逐个传递给函数,并且该列将被传递。 lm函数将只会看到一个两列数据框,并且每次“读”列都将是因变量。无需花哨取代:

models <- sapply(varlist, function(x) { 
lm(read ~ ., data = hsb2[, c("read", x) ]) 
}, simplify=FALSE) 

> summary(models[[1]]) # The first model. Note the use of "[[" 

Call: 
lm(formula = read ~ ., data = hsb2[, c("read", x)]) 

Residuals: 
    Min  1Q Median  3Q  Max 
-19.8565 -5.8976 -0.8565 5.5801 24.2703 

Coefficients: 
      Estimate Std. Error t value Pr(>|t|)  
(Intercept) 18.16215 3.30716 5.492 1.21e-07 *** 
write  0.64553 0.06168 10.465 < 2e-16 *** 
--- 
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 8.248 on 198 degrees of freedom 
Multiple R-squared: 0.3561, Adjusted R-squared: 0.3529 
F-statistic: 109.5 on 1 and 198 DF, p-value: < 2.2e-16 

对于所有型号::

lapply(models, summary) 
+0

不错。使用'sapply(...,simplify = FALSE)'而不是'lapply'也会保留这个名字,并且允许你像'models $ write'这样的子集合。 – thelatemail 2014-09-23 05:53:01

+0

好的mod。将编辑。 – 2014-09-23 05:59:29

+0

清除要用'lapply()'坚持,然后命名结果。 – hadley 2014-09-23 17:27:25

4

akrun借我的回答那天晚上,现在我(部分)借用他的。

do.call将变量放入call输出中,以便正确读取。这是简单回归的一般功能。

doModel <- function(col1, col2, data = hsb2, FUNC = "lm") 
{ 
    form <- as.formula(paste(col1, "~", col2)) 
    do.call(FUNC, list(form, substitute(data))) 
}  

lapply(varlist, doModel, col1 = "read") 
# [[1]] 
# 
# Call: 
# lm(formula = read ~ write, data = hsb2) 
# 
# Coefficients: 
# (Intercept)  write 
#  18.1622  0.6455 
# 
# 
# [[2]] 
# 
# Call: 
# lm(formula = read ~ math, data = hsb2) 
# 
# Coefficients: 
# (Intercept)   math 
#  14.0725  0.7248 
# 
# ... 
# ... 
# ... 

注:由于thelatemail提到在他的评论

sapply(varlist, doModel, col1 = "read", simplify = FALSE) 

将保持名称列表中,也允许list$name子集。

+0

+1确认:-) – akrun 2014-09-23 09:45:04

+0

感谢您的解释! – olala 2014-09-23 19:50:24