【问题标题】:R boxcox not workingR boxcox 不工作
【发布时间】:2018-05-21 02:31:48
【问题描述】:
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) 时,它给了我这个错误。我做错了什么?

【问题讨论】:

    标签: r object types closures


    【解决方案1】:

    这是一个特别模糊且无用的错误,但如果您了解what a "closure" is,那么它可能会提供有关查找位置的见解。不幸的是,在这里找到它有点困难......

    TL;DR

    将您的变量从formula 重命名为任何其他不是函数名称的名称。例如,如果您使用 frm &lt;- 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>
    

    哦。因此,在最近对lm 的调用中引用的formula 没有返回到原始调用环境,即使使用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)
    

    然后一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-17
      • 2020-02-04
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多