附加到公式的正确方法,其中公式和要附加的东西都是参数

时间:2013-02-12 18:53:38

标签: r formula

我已经在SO上做了相当多的阅读,并了解到我通常应该避免将formula objects作为字符串进行操作,但我还没有找到如何以安全的方式执行此操作:

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))
}

2 个答案:

答案 0 :(得分: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指出的那样,deparsesubstitute解决了我的问题:我已经添加了tf2作为代码示例的更好选项,因此您可以看到两者是如何工作的。

答案 1 :(得分: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

另请参阅此问题的姐妹问题的答案,我建议使用与xyplot类似的内容:https://stackoverflow.com/a/14858661/210673