data1 <- read.csv("~/Desktop/Group_22.csv")
View(data1)
E_var <- regmatches(names(data1), regexpr("(E[0-9])+", names(data1)))
G_var <- regmatches(names(data1), regexpr("(G[0-9]*)+", names(data1)))
(E_vs_G <- paste0(c(gsub(" ", "*", outer(E_var, G_var, paste))), collapse = "+"))
(G_eff_1 <- paste("I(", G_var, ")", collapse="+"))
(G_eff_2 <- paste("I(", apply( combn(G_var, 2), 2, paste, collapse="*"), ")", collapse="+"))
(G_eff_3 <- paste("I(", apply( combn(G_var, 3), 2, paste, collapse="*"), ")", collapse="+"))
(E_eff <- paste0("I(", E_var,"^2", ")", collapse = "+"))
(formula <- paste( "I(log(Y)) ~" , paste(c(E_eff, G_eff_1, G_eff_2, G_eff_3, E_vs_G), collapse = "+")))
M <- lm(formula, data=data1)
summary(M)
anova(M)
install.packages('MASS')
library(MASS)
boxcox(M)
Error: object of type 'closure' is not subsettable
代码运行正常,除非它到达boxcox(M),它给了我那个错误。我做错了什么?
答案 0 :(得分:1)
这是一个特别模糊且无用的错误,但如果您了解what a "closure" is,则可能会提供有关查看位置的信息。不幸的是,在这里找到它有点困难......
将变量从formula
重命名为其他任何非函数名称的变量。例如,如果使用frm <- paste(...)
,则代码可以正常工作。
注意:这是一个典型的例子,说明为什么你应该避免将变量命名为与函数相同。通常,您会看到名为data
的变量。在这种情况下,formula
是一个函数,由于包搜索路径,找不到您期望的顺序。
要找出原因,首先我们需要调试被调用的特定函数。我们可以使用debug(boxcox)
并逐步进入它,或者我们可以执行debug(MASS:::boxcox.lm)
以确保我们调试正确的方法。无论如何......
boxcox(M)
# debugging in: boxcox.lm(M)
# debug: {
# m <- length(lambda)
# if (is.null(object$y) || is.null(object$qr))
# object <- update(object, y = TRUE, qr = TRUE, ...)
# result <- NextMethod()
# if (plotit)
# invisible(result)
# else result
# }
单步执行此操作后,调用update
失败。信息量不大,我们需要介入其中。我们可以使用s
进入该功能。 (顺便说一下,它使用MASS:::update.loglm
,而不是导出功能。)
# Browse[2]>
s
# debugging in: update(object, y = TRUE, qr = TRUE, ...)
# debug: UseMethod("update")
# Browse[3]>
s
# debugging in: update.default(object, y = TRUE, qr = TRUE, ...)
# debug: {
# if (is.null(call <- getCall(object)))
# stop("need an object with call component")
# extras <- match.call(expand.dots = FALSE)$...
# if (!missing(formula.))
# call$formula <- update.formula(formula(object), formula.)
# if (length(extras)) {
# existing <- !is.na(match(names(extras), names(call)))
# for (a in names(extras)[existing]) call[[a]] <- extras[[a]]
# if (any(!existing)) {
# call <- c(as.list(call), extras[!existing])
# call <- as.call(call)
# }
# }
# if (evaluate)
# eval(call, parent.frame())
# else call
# }
单步执行此操作后,它会在最后一个命令eval(call, parent.frame())
上失败。还不是很有帮助,但在查看R认为它正在使用的变量时进行故障排除很有用。例如,早些时候:
# Browse[2]>
object
# Call:
# lm(formula = formula, data = data1)
# Coefficients:
# (Intercept) I(cyl^2) I(disp^2) I(hp) I(drat) I(hp * drat) cyl
# 3.274e+00 -2.006e-02 9.589e-06 -1.250e-02 2.388e-01 5.869e-04 4.034e-01
# hp disp drat cyl:hp hp:disp cyl:drat disp:drat
# NA -9.728e-03 NA 2.122e-03 -2.418e-05 -1.155e-01 2.064e-03
好的,这看起来很正确。接下来,意识到eval
调用正试图通过对其进行更新来回忆起以前的模型。
# Browse[4]>
call
# lm(formula = formula, data = data1)
这与我们第一次称呼它的方式类似。但是,查看实际变量,data1
看起来是正确的但是......
# Browse[4]>
formula
# function (x, ...)
# UseMethod("formula")
# <bytecode: 0x000000001a5c20a0>
# <environment: namespace:stats>
喔。因此,最近对formula
的调用中引用的lm
未回复到原始调用环境,即使使用eval(...,parent.frame())
也是如此。
如果您改为使用:
(frm <- paste( "I(log(Y)) ~" , paste(c(E_eff, G_eff_1, G_eff_2, G_eff_3, E_vs_G), collapse = "+")))
M <- lm(frm, data=data1)
然后事情就好了。