为什么替代公式适用于 lm 和 oneway.test,但不适用于 aov?
Why does a substituted formula work for lm and oneway.test, but not aov?
example <- data.frame(
var1 = c(1, 2, 3, 4, 5, 6, 7, 8),
class = c(rep(1, 4), rep(2, 4))
)
example$class <- as.factor(example$class)
This question 提供了使用替代和 as.name 为 aov
创建公式的修复,但我不明白为什么该公式适用于 oneway.test
和lm
。有人可以解释一下吗?
fm <- substitute(i ~ class, list(i = as.name('var1')))
oneway.test(fm, example)
One-way analysis of means (not assuming equal variances)
data: var1 and class
F = 19.2, num df = 1, denom df = 6, p-value = 0.004659
lm(fm, example)
Call:
lm(formula = fm, data = example)
Coefficients:
(Intercept) class2
2.5 4.0
aov(fm, example)
Error in terms.default(formula, "Error", data = data) :
no terms component nor attribute
问题是 substitute
正在返回一个未评估的调用,而不是一个公式。比较
class(substitute(a~b))
# [1] "call"
class(a~b)
# [1] "formula"
如果你评估它(就像在另一个答案中所做的那样),两者都会起作用
fm <- eval(substitute(i ~ class, list(i = as.name('var1'))))
oneway.test(fm, example)
aov(fm, example)
您收到的错误消息来自 terms
函数,该函数由 aov()
调用。此函数需要对公式进行操作,而不是调用。这基本上就是正在发生的事情
# ok
terms(a~b)
# doesn't work
unf <- quote(a~b) #same as substitute(a~b)
terms(unf)
# Error in terms.default(unf) : no terms component nor attribute
# ok
terms(eval(unf))
差异的一个可能来源是 fm
实际上是 call
而不是 formula
并且显然某些函数进行转换而其他函数不进行转换。
如果你这样做:
fm <- as.formula(fm)
然后对 aov
的调用将起作用。
example <- data.frame(
var1 = c(1, 2, 3, 4, 5, 6, 7, 8),
class = c(rep(1, 4), rep(2, 4))
)
example$class <- as.factor(example$class)
This question 提供了使用替代和 as.name 为 aov
创建公式的修复,但我不明白为什么该公式适用于 oneway.test
和lm
。有人可以解释一下吗?
fm <- substitute(i ~ class, list(i = as.name('var1')))
oneway.test(fm, example)
One-way analysis of means (not assuming equal variances)
data: var1 and class
F = 19.2, num df = 1, denom df = 6, p-value = 0.004659
lm(fm, example)
Call:
lm(formula = fm, data = example)
Coefficients:
(Intercept) class2
2.5 4.0
aov(fm, example)
Error in terms.default(formula, "Error", data = data) :
no terms component nor attribute
问题是 substitute
正在返回一个未评估的调用,而不是一个公式。比较
class(substitute(a~b))
# [1] "call"
class(a~b)
# [1] "formula"
如果你评估它(就像在另一个答案中所做的那样),两者都会起作用
fm <- eval(substitute(i ~ class, list(i = as.name('var1'))))
oneway.test(fm, example)
aov(fm, example)
您收到的错误消息来自 terms
函数,该函数由 aov()
调用。此函数需要对公式进行操作,而不是调用。这基本上就是正在发生的事情
# ok
terms(a~b)
# doesn't work
unf <- quote(a~b) #same as substitute(a~b)
terms(unf)
# Error in terms.default(unf) : no terms component nor attribute
# ok
terms(eval(unf))
差异的一个可能来源是 fm
实际上是 call
而不是 formula
并且显然某些函数进行转换而其他函数不进行转换。
如果你这样做:
fm <- as.formula(fm)
然后对 aov
的调用将起作用。