5

I'm using the emmeans package and cannot understand why this works

library(emmeans)
mod <- lm(mpg ~ disp + hp, data = mtcars)
l1 <- emmeans(mod, list("disp","hp"))

for (x in l1) {print(data.frame(x))}

      disp   emmean        SE df lower.CL upper.CL
1 230.7219 20.09062 0.5527102 29 18.96021 21.22104
        hp   emmean        SE df lower.CL upper.CL
1 146.6875 20.09062 0.5527102 29 18.96021 21.22104

but this doesn't?

lapply(l1, function(x) data.frame(x))

 Error in as.data.frame.default(x[[i]], optional = TRUE) : 
cannot coerce class ‘"function"’ to a data.frame

With a normal list I get the expected output (data frames in list):

l2 <- list(a=matrix(c(1,2,3,4)), b=matrix(c(5,6,7,8)))
lapply(l2, function(x) data.frame(x))
$a
  x
1 1
2 2
3 1
4 3

$b
  x
1 4
2 5
3 4
4 6
locus
  • 387
  • 2
  • 9

1 Answers1

2

It does modify the class from emmGrid to list with lapply

> lapply(l1, class)
$`emmeans of disp`
[1] "list"

$`emmeans of hp`
[1] "list"

versus, looping over the sequence and extraction doesn't

> lapply(seq_along(l1), \(i) class(l1[[i]]))
[[1]]
[1] "emmGrid"
attr(,"package")
[1] "emmeans"

[[2]]
[1] "emmGrid"
attr(,"package")
[1] "emmeans"

Thus, as.data.frame.list will be applied on all the elements of the list (which may have different structure, lengths etc). An option is to use as_tibble with map

library(tibble)
library(purrr)
> map(l1, as_tibble)
$`emmeans of disp`
# A tibble: 1 × 6
   disp emmean    SE    df lower.CL upper.CL
  <dbl>  <dbl> <dbl> <dbl>    <dbl>    <dbl>
1  231.   20.1 0.553    29     19.0     21.2

$`emmeans of hp`
# A tibble: 1 × 6
     hp emmean    SE    df lower.CL upper.CL
  <dbl>  <dbl> <dbl> <dbl>    <dbl>    <dbl>
1  147.   20.1 0.553    29     19.0     21.2
akrun
  • 874,273
  • 37
  • 540
  • 662