How to correctly `dput` a fitted linear model (by `lm`) to an ASCII file and recreate it later?

前端 未结 2 1538
借酒劲吻你
借酒劲吻你 2020-12-18 01:09

I want to persist a lm object to a file and reload it into another program. I know I can do this by writing/reading a binary file via saveRDS/

2条回答
  •  北海茫月
    2020-12-18 01:54

    This is an important update!

    As mentioned in the previous answer, the most challenging bit is to recover $terms as best as we can. The suggested method using terms.formula works for OP's example, but not for the following with bs() and poly():

    dat <- data.frame(x1 = runif(20), x2 = runif(20), x3 = runif(20), y = rnorm(20))
    library(splines)
    fit <- lm(y ~ bs(x1, df = 3) + poly(x2, degree = 3) + x3, data = dat)
    rm(dat)
    

    If we follow the previous answer:

    dput(fit, control = c("quoteExpressions", "showAttributes"), file = "model.R") 
    fit1 <- source("model.R")$value
    fit1$terms <- terms.formula(fit1$terms)
    

    We will see that summary.lm and anova.lm work correctly, but not predict.lm:

    predict(fit1, newdata = data.frame(x1 = 0.5, x2 = 0.5, x3 = 0.5))
    

    Error in bs(x1, df = 3) : could not find function "bs"

    This is because ".Environment" attribute of $terms is missing. We need

    environment(fit1$terms) <- .GlobalEnv
    

    Now run above predict again we see a different error:

    Error in poly(x2, degree = 3) :

    'degree' must be less than number of unique points

    This is because we are missing "predvars" attributes for safe / correct prediction of bs() and poly().

    A remedy is that we need to dput such special attribute additionally:

    dput(attr(fit$terms, "predvars"), control = "quoteExpressions", file = "predvars.R")
    

    then read and add it

    attr(fit1$terms, "predvars") <- source("predvars.R")$value
    

    Now running predict works correctly.

    Note that "dataClass" attribute of $terms is also missing, but this does not seem to cause any problem for any generic functions.

提交回复
热议问题