2

我已经在 SO 上进行了大量阅读,并了解到我通常应该避免操作formula objectsas 字符串,但我还没有完全找到如何以安全的方式做到这一点:

tf <- function(formula = NULL, data = NULL, groups = NULL, ...) {
# Arguments are unquoted and in the typical form for lm etc
# Do some plotting with lattice using formula & groups (works, not shown)
# Append 'groups' to 'formula':
# Change y ~ x as passed in argument 'formula' to
# y ~ x * gr where gr is the argument 'groups' with
# scoping so it will be understood by aov
new_formula <- y ~ x * gr
# Now do some anova (could do if formula were right)
model <- aov(formula = new_formula, data = data)
# And print the aov table on the plot (can do)
print(summary(model)) # this will do for testing
}

也许我来的最接近的是使用reformulate,但这仅提供+RHS,而不是*. 我想使用这样的功能:

p <- tf(carat ~ color, groups = clarity, data = diamonds)

并获得克拉 ~ 颜色 * 净度的 aov 结果。提前致谢。

解决方案

这是基于@Aaron 的评论的工作版本,它演示了正在发生的事情:

tf <- function(formula = NULL, data = NULL, groups = NULL, ...) {
print(deparse(substitute(groups)))
f <- paste(".~.*", deparse(substitute(groups)))
new_formula <- update.formula(formula, f)
print(new_formula)
model <- aov(formula = new_formula, data = data)
print(summary(model))
}
4

2 回答 2

3

我认为 update.formula 可以解决您的问题,但是我在函数调用中遇到了更新问题。它将像我在下面编码的那样工作,但请注意,我将列传递给组,而不是变量名。然后将该列添加到函数数据集,然后更新工作。

我也不知道它是否完全符合您在第二个等式中的要求,但请查看 update.formula 的帮助文件并稍微弄乱一下。

http://stat.ethz.ch/R-manual/R-devel/library/stats/html/update.formula.html

tf <- function(formula,groups,d){
  d$groups=groups
  newForm = update(formula,~.*groups)
  mod = lm(newForm,data=d)
}

dat  = data.frame(carat=rnorm(10,0,1),color=rnorm(10,0,1),color2=rnorm(10,0,1),clarity=rnorm(10,0,1))
m = tf(carat~color,dat$clarity,d=dat)
m2 = tf(carat~color+color2,dat$clarity,d=dat)

tf2 <- function(formula, group, d) {
  f <- paste(".~.*", deparse(substitute(group)))
  newForm <- update.formula(formula, f)
  lm(newForm, data=d)
}
mA = tf2(carat~color,clarity,d=dat)
m2A = tf2(carat~color+color2,clarity,d=dat)

编辑:正如@Aaron 指出的那样,它deparse解决substitute了我的问题:我已将tf2其作为更好的选项添加到代码示例中,这样您就可以看到两者是如何工作的。

于 2013-02-12T19:17:23.180 回答
0

当我在函数内定义和调用函数时遇到问题时,我使用的一种技术是将参数作为字符串传递,然后从这些字符串构造函数内的调用。这就是这里的样子。

tf <- function(formula, data, groups) {
  f <- paste(".~.*", groups)
  m <- eval(call("aov", update.formula(as.formula(formula), f), data = as.name(data)))
  summary(m)
}

tf("mpg~vs", "mtcars", "am") 

有关此示例的另一个示例,请参见我之前的一个问题的答案:https ://stackoverflow.com/a/7668846/210673 。

另请参阅此问题的姊妹问题的答案,我建议使用类似的方法xyplothttps ://stackoverflow.com/a/14858661/210673

于 2013-02-13T16:48:39.950 回答