【问题标题】:lmer returns error when run inside a functionlmer 在函数内运行时返回错误
【发布时间】:2017-11-15 21:40:49
【问题描述】:

我正在尝试制作一个适合所选变量的混合模型的函数。

如果我在函数内部运行这个命令:

lme4::lmer(VAR ~ cVAR + (1|ID), data=df) 

我得到错误:

Error in model.frame.default(data = df, drop.unused.levels = TRUE, formula = VAR ~  : 
  variable lengths differ (found for 'ID')

我已经以多种方式测试了我的代码,但我无法找出问题所在。我可以从函数内部毫无问题地绘制图。如果我尝试仅打印函数内部使用的数据框,它看起来与我想要的完全一样。 此外 - 如果我在函数之外运行 lmer 命令(用 VAR 和 cVAR 代替 X 和 cX),则命令运行没有问题。

因此,我认为该错误是由在函数内部运行 lmer() 引起的。 This Question 有类似的问题,但错误消息与我不同。

有什么方法可以在函数内部运行 lmer 而不会出现错误?

可重现的例子:

  set.seed(1)

org <- data.frame(
  X = rep(1:10+rnorm(10,mean=1,sd=0.5),2),
  cX = rep(1:10+rnorm(10,mean=1,sd=0.5),2),
  Y = rep(1:10+rnorm(10,mean=1,sd=0.5), 2),
  cY = rep(1:10-rnorm(10,mean=1,sd=0.5),2),
  Frame = rep(1:5, 4),
  JN = rep(1:2, each=5),
  ID = rep(1:2, each=10))

FUNC <- function(VAR) {
  VAR <- deparse(substitute(VAR))
  cVAR <- paste0("c", VAR)
  df <- dplyr::select(org, ID, JN, Frame, VAR, cVAR) # Keeping only a subset of the data
  df <- df %>% tidyr::drop_na() #Keeping only complete cases

  stopifnot(all(c(VAR, cVAR) %in% names(df)))

  MixedModel <- lme4::lmer(VAR ~ cVAR + (1|ID), data=df)
  b <- plot(MixedModel)
}

#It works fine outside the function:
MixedModel_no_FUNC <- lme4::lmer(X ~ cX + (1|ID), data=org)
plot(MixedModel_no_FUNC)

#But not inside the function
FUNC(X)

我的 sessionInfo 以防万一

R version 3.4.1 (2017-06-30)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=Danish_Denmark.1252  LC_CTYPE=Danish_Denmark.1252   
[3] LC_MONETARY=Danish_Denmark.1252 LC_NUMERIC=C                   
[5] LC_TIME=Danish_Denmark.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] lme4_1.1-14          Matrix_1.2-10        ggExtra_0.7          BlandAltmanLeh_0.3.1
 [5] gganimate_0.1.0.9000 gridExtra_2.3        bindrcpp_0.2         dplyr_0.7.3         
 [9] purrr_0.2.3          readr_1.1.1          tidyr_0.7.1          tibble_1.3.4        
[13] tidyverse_1.1.1      ggmap_2.7            ggplot2_2.2.1       

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.13      lubridate_1.6.0   lattice_0.20-35   png_0.1-7         assertthat_0.2.0 
 [6] digest_0.6.12     psych_1.7.8       mime_0.5          R6_2.2.2          cellranger_1.1.0 
[11] plyr_1.8.4        httr_1.3.1        RgoogleMaps_1.4.1 rlang_0.1.2       lazyeval_0.2.0   
[16] readxl_1.0.0      minqa_1.2.4       geosphere_1.5-7   miniUI_0.1.1      nloptr_1.0.4     
[21] splines_3.4.1     proto_1.0.0       labeling_0.3      stringr_1.2.0     foreign_0.8-69   
[26] munsell_0.4.3     shiny_1.0.5       broom_0.4.2       compiler_3.4.1    httpuv_1.3.5     
[31] modelr_0.1.1      pkgconfig_2.0.1   mnormt_1.5-5      htmltools_0.3.6   tidyselect_0.2.1 
[36] MASS_7.3-47       bitops_1.0-6      grid_3.4.1        nlme_3.1-131      jsonlite_1.5     
[41] xtable_1.8-2      gtable_0.2.0      magrittr_1.5      scales_0.5.0      stringi_1.1.5    
[46] mapproj_1.2-5     reshape2_1.4.2    sp_1.2-5          xml2_1.1.1        rjson_0.2.15     
[51] tools_3.4.1       forcats_0.2.0     glue_1.1.1        maps_3.2.0        hms_0.3          
[56] jpeg_0.1-8        parallel_3.4.1    yaml_2.1.14       colorspace_1.3-2  rvest_0.3.2      
[61] knitr_1.17        bindr_0.1         haven_1.1.0   

【问题讨论】:

    标签: r function lme4


    【解决方案1】:

    您的数据框中的对象名称和函数中的环境存在一些冲突的名称。这是您的数据:

    org <- data.frame(
        X = rep(1:10+rnorm(10,mean=1,sd=0.5),2),
        cX = rep(1:10+rnorm(10,mean=1,sd=0.5),2),
        Y = rep(1:10+rnorm(10,mean=1,sd=0.5), 2),
        cY = rep(1:10-rnorm(10,mean=1,sd=0.5),2),
        Frame = rep(1:5, 4),
        JN = rep(1:2, each=5),
        ID = rep(1:2, each=10))
    

    我选择只将字符串传递给 VAR 参数,而不是像您那样进行解析。然后检查 VAR 和 cVAR 是否在数据框中。然后我减少数据框并将 VAR 和 cVAR 重命名为 Y 和 X,这样当您调用 lmer() 时,您可以确定公式指的是 data.frame 中的变量,而不是函数环境中的对象。

    library(lme4)
    FUNC <- function(VAR = "VAR", df) {
        cVAR <- paste0("c", VAR)
        stopifnot(all(c(VAR, cVAR) %in% names(df)))
        df <- df[,c("ID", "JN", "Frame", VAR, cVAR)]
        names(df) <- c(c("ID", "JN", "Frame", "Y", "X"))
        df <- df[complete.cases(df),]
        MixedModel <- lme4::lmer(Y ~ X + (1|ID), data=df)
        plot(MixedModel)
    }
    
    FUNC(VAR = "X", df = org)
    

    【讨论】:

    • 谢谢 - 它有效,我自己永远也想不通 :-) 我不知道为什么用:ggplot(df, aes_string(x=VAR, y=cVAR))+geom_point() 进行绘图没有产生相同类型的错误。你能帮我理解吗?
    • 我不是这个问题原因的专家,但之前已经处理过几次,所以我尽量避免在调用对象时在函数中使用相同的对象名称全局和函数环境。一个很好的资源供您开始阅读:adv-r.had.co.nz/Environments.html
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 2017-09-20
    • 2013-01-17
    • 2022-08-04
    • 2021-10-04
    相关资源
    最近更新 更多