Home > front end >  Extract R^2 from a lm within a dply chain as opposed to attributes(mylm)$adj.rsquared
Extract R^2 from a lm within a dply chain as opposed to attributes(mylm)$adj.rsquared

Time:09-28

According to this old post, one can get adjusted Rquared from a model with summary(lm(speed~dist, cars))$r.squared

Suppose I have a model already defined and I want get adjusted rquared, is there an equivalent dplyr way?

(Why am I doing this? Because I have a lm field as part of a list column and I would like to pass this model as .x and get the R^2 from it and display it using map_dbl())

Tried working on an example from my list column:

x <- plist$lm[[1]]
> summary(x)$adj.r.squared
[1] 0.8500937

I need to get this within a map() function though so tried:

x %>% summary() %>% pull(adj.r.squared)
Error in UseMethod("pull") : 
  no applicable method for 'pull' applied to an object of class "summary.lm"

x %>% summary()$adj.r.squared
Error in .$summary() : 3 arguments passed to '$' which requires 2

How can I get adjusted R2 using pipe operator %>% in this way?

CodePudding user response:

You can use broom::glance to get a summary of a model as a tibble, and then since it's a tibble dplyr functions will work.

library(dplyr, warn.conflicts = FALSE)
library(broom)

lm(speed ~ dist, cars) %>% 
  glance()
#> # A tibble: 1 × 12
#>   r.squared adj.r.squared sigma statistic  p.value    df logLik   AIC   BIC
#>       <dbl>         <dbl> <dbl>     <dbl>    <dbl> <dbl>  <dbl> <dbl> <dbl>
#> 1     0.651         0.644  3.16      89.6 1.49e-12     1  -127.  261.  267.
#> # … with 3 more variables: deviance <dbl>, df.residual <int>, nobs <int>

lm(speed ~ dist, cars) %>% 
  glance() %>% 
  pull(adj.r.squared)
#> [1] 0.6438102

Created on 2021-09-27 by the reprex package (v2.0.1)

CodePudding user response:

As the error message suggests, pull may not work with a class of summary.lm. Based on the documentation, the usage is

pull(.data, var = -1, name = NULL, ...)

.data - A data frame, data frame extension (e.g. a tibble), or a lazy data frame (e.g. from dbplyr or dtplyr)

Here, the data coming from summary is of class summary.lm and not any of the data.frame/tibble/data.table. Therefore use one of the methods that work on a list (summaryreturns alist) i..e $or[[`

library(magrittr)
x %>% 
    summary %>%
    .$adj.r.squared

Or with the alias extract2 from magrittr

x %>%
    summary %>%
    extract2("adj.r.squared")

or may also use pluck from purrr

library(purrr)
x %>%
     summary %>% 
        pluck("adj.r.squared")
  •  Tags:  
  • r
  • Related