lmer在函数内运行时返回错误

时间:2017-11-15 21:40:49

标签: r function lme4

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

如果我在函数中运行此命令:

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   

1 个答案:

答案 0 :(得分: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)