Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pool() on lavaan fit objects gives error: coef() not available on S4 object #615

Closed
Gootjes opened this issue Jan 14, 2024 · 2 comments · Fixed by #616
Closed

pool() on lavaan fit objects gives error: coef() not available on S4 object #615

Gootjes opened this issue Jan 14, 2024 · 2 comments · Fixed by #616
Labels

Comments

@Gootjes
Copy link

Gootjes commented Jan 14, 2024

Before submitting the issue

  • Check whether a bug report is the right format for your issue. For questions about using the mice package, see Discussions. For theoretical background about the mice methods, see Flexible Imputation of Missing Data.
  • Please make sure that you are using the latest version of mice (e.g. with the packageVersion() or sessionInfo() function).
  • Please verify whether the bug has already been addressed (e.g. on GitHub or Stack Overflow.

Describe the bug
The error happens in get.dfcom on this line

return(as.numeric(max(nobs - length(coef(model)), 1)))

The package lavaan implements coef as an S4 function (compare lavaan::coef to stats::coef), however, this function is not available at this point, so the regular coef function is called on the lavaan fit object, leading to an error.

To Reproduce

library(lavaan)
#> This is lavaan 0.6-15
#> lavaan is FREE software! Please report any bugs.
library(mice)
#> 
#> Attaching package: 'mice'
#> The following object is masked from 'package:stats':
#> 
#>     filter
#> The following objects are masked from 'package:base':
#> 
#>     cbind, rbind
pool(list(sem("mpg ~ cyl", data = mtcars[1:10,]), sem("mpg ~ cyl", data = mtcars[1:20,])))
#> Error in object$coefficients: $ operator not defined for this S4 class

Created on 2024-01-14 with reprex v2.0.2

Expected behavior
That coef() works.

A solution would be to make get.dfcom a S3method, such that get.dfcom.default is the current function, and custom functions are implemented for lavaan and coxph (and in the future others?)

@Gootjes Gootjes added the bug label Jan 14, 2024
@hanneoberman
Copy link
Member

I believe this is not a bug in mice but a problem with the lavaan fit object not being processed as expected by broom::tidy().

library(lavaan)
#> This is lavaan 0.6-15
#> lavaan is FREE software! Please report any bugs.
library(mice)
#> 
#> Attaching package: 'mice'
#> The following object is masked from 'package:stats':
#> 
#>     filter
#> The following objects are masked from 'package:base':
#> 
#>     cbind, rbind
sem("hgt ~ age", data = boys)
#> lavaan 0.6.15 ended normally after 1 iteration
#> 
#>   Estimator                                         ML
#>   Optimization method                           NLMINB
#>   Number of model parameters                         2
#> 
#>                                                   Used       Total
#>   Number of observations                           728         748
#> 
#> Model Test User Model:
#>                                                       
#>   Test statistic                                 0.000
#>   Degrees of freedom                                 0
imp <- mice(boys, print = FALSE)
fit <- with(imp, sem("hgt ~ age"))
pool(fit)
#> Warning in get.dfcom(object, dfcom): Infinite sample size assumed.
#> Warning: The `exponentiate` argument is not supported in the `tidy()` method
#> for `lavaan` objects and will be ignored.
#> Error in `purrr::keep()`:
#> ℹ In index: 1.
#> ℹ With name: estimate.
#> Caused by error in `lavaan::parameterEstimates()`:
#> ! unused arguments (effects = "fixed", parametric = TRUE, exponentiate = FALSE)
#> Backtrace:
#>      ▆
#>   1. ├─mice::pool(fit)
#>   2. │ └─mice:::pool.fitlist(...)
#>   3. │   ├─base::summary(fitlist, type = "tidy", exponentiate = FALSE)
#>   4. │   └─mice:::summary.mira(fitlist, type = "tidy", exponentiate = FALSE)
#>   5. │     ├─... %>% bind_rows()
#>   6. │     └─base::lapply(...)
#>   7. │       ├─generics (local) FUN(X[[i]], ...)
#>   8. │       └─broom:::tidy.lavaan(X[[i]], ...)
#>   9. │         └─... %>% as_tibble()
#>  10. ├─dplyr::bind_rows(.)
#>  11. │ └─rlang::list2(...)
#>  12. ├─tibble::as_tibble(.)
#>  13. ├─dplyr::select(...)
#>  14. ├─broom:::rename2(...)
#>  15. │ └─purrr::keep(dots, ~quo_name(.x) %in% colnames(.data))
#>  16. │   └─purrr:::where_if(.x, .p, ...)
#>  17. │     └─purrr:::map_(.x, .p, ..., .type = "logical", .purrr_error_call = .purrr_error_call)
#>  18. │       ├─purrr:::with_indexed_errors(...)
#>  19. │       │ └─base::withCallingHandlers(...)
#>  20. │       ├─purrr:::call_with_cleanup(...)
#>  21. │       └─purrr (local) .f(.x[[i]], ...)
#>  22. │         └─broom (local) .fn(...)
#>  23. │           ├─quo_name(.x) %in% colnames(.data)
#>  24. │           └─base::colnames(.data)
#>  25. │             └─base::is.data.frame(x)
#>  26. ├─dplyr::mutate(., term = paste(lhs, op, rhs))
#>  27. ├─tibble::rownames_to_column(.)
#>  28. ├─tibble::as_tibble(.)
#>  29. └─base::.handleSimpleError(...)
#>  30.   └─purrr (local) h(simpleError(msg, call))
#>  31.     └─cli::cli_abort(...)
#>  32.       └─rlang::abort(...)
rlang::last_trace()
#> Error: Can't show last error because no error was recorded yet

Created on 2024-01-15 with reprex v2.0.2

@Gootjes
Copy link
Author

Gootjes commented Jan 15, 2024

To clarify, my reprex does not reproduce the error on your machine?

That bug you found in your reprex is reported here: #614

I believe you are not running into the bug I am reporting because the sem models aren't fitted because the data argument isn't provided to lavaan::sem by mice:::with.mids. The calls on the non-fitted models never reach the offending line of code.

print(fit)
# (...)
#> lavaan 0.6.17 did not run (perhaps do.fit = FALSE)?

New reprex that reproduces the bug:

library(lavaan)
#> This is lavaan 0.6-17
#> lavaan is FREE software! Please report any bugs.
library(mice)
#> 
#> Attaching package: 'mice'
#> The following object is masked from 'package:stats':
#> 
#>     filter
#> The following objects are masked from 'package:base':
#> 
#>     cbind, rbind
imp <- mice(boys, print = FALSE)
fit <- as.mira(lapply(1:5, function(i) sem("hgt ~ age", data = complete(imp, i))))
pool(fit)
#> Error in object$coefficients: $ operator not defined for this S4 class

Created on 2024-01-15 with reprex v2.0.2

@hanneoberman hanneoberman linked a pull request Jan 19, 2024 that will close this issue
stefvanbuuren added a commit that referenced this issue Apr 17, 2024
…ves-error-coef-not-available-on-s4-object

Add `stats` namespace to `coef()` to fix #615
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants