ddsjoberg / gtsummary

Presentation-Ready Data Summary and Analytic Result Tables
http://www.danieldsjoberg.com/gtsummary
Other
1.06k stars 128 forks source link

tbl_regression(): Label not displaying when using Hmisc::rcspline.eval #312

Closed ddsjoberg closed 4 years ago

ddsjoberg commented 4 years ago
library(tidyverse)
library(Hmisc)
library(gtsummary)
lm(
  marker ~ rcspline.eval(age, inclx = TRUE),
  trial
) %T>%
  {print(broom::tidy(.))} %>%
  tbl_regression()
#> # A tibble: 5 x 5
#>   term                              estimate std.error statistic p.value
#>   <chr>                                <dbl>     <dbl>     <dbl>   <dbl>
#> 1 (Intercept)                        0.726      0.524     1.39     0.168
#> 2 rcspline.eval(age, inclx = TRUE)x  0.00158    0.0187    0.0848   0.933
#> 3 rcspline.eval(age, inclx = TRUE)   0.0503     0.0980    0.513    0.608
#> 4 rcspline.eval(age, inclx = TRUE)  -0.210      0.597    -0.351    0.726
#> 5 rcspline.eval(age, inclx = TRUE)   0.0744     0.968     0.0769   0.939

Created on 2019-12-11 by the reprex package (v0.3.0) image

mljaniczek commented 4 years ago

I added a check to parse_fit() util function to see if the model.frame() object of the model input is a data.frame with vector elements. If it is not, a message will print to the user to notify them that it may affect tbl_regression() output. #315

In this case, the model.frame for an object with splines has matrix elements within the data.frame list, so the new check would at least throw the user a message.

ddsjoberg commented 4 years ago

I think in this case the matrix is passing the rlang::is_vector() check. We'll have to revisit this on another release....

library(tidyverse)
library(Hmisc)
#> Loading required package: lattice
#> Loading required package: survival
#> Loading required package: Formula
#> 
#> Attaching package: 'Hmisc'
#> The following objects are masked from 'package:dplyr':
#> 
#>     src, summarize
#> The following objects are masked from 'package:base':
#> 
#>     format.pval, units
library(gtsummary)
tt <-
  lm(
    marker ~ rcspline.eval(age, inclx = TRUE),
    trial
  ) %>%
  model.frame()

map(tt, class)
#> $marker
#> [1] "numeric"
#> 
#> $`rcspline.eval(age, inclx = TRUE)`
#> [1] "matrix"

map(tt, is.vector)
#> $marker
#> [1] FALSE
#> 
#> $`rcspline.eval(age, inclx = TRUE)`
#> [1] FALSE
map(tt, rlang::is_vector)
#> $marker
#> [1] TRUE
#> 
#> $`rcspline.eval(age, inclx = TRUE)`
#> [1] TRUE
map(tt, rlang::is_bare_vector)
#> $marker
#> [1] TRUE
#> 
#> $`rcspline.eval(age, inclx = TRUE)`
#> [1] TRUE
map(tt, rlang::is_scalar_vector)
#> $marker
#> [1] FALSE
#> 
#> $`rcspline.eval(age, inclx = TRUE)`
#> [1] FALSE
map(tt, is.atomic)
#> $marker
#> [1] TRUE
#> 
#> $`rcspline.eval(age, inclx = TRUE)`
#> [1] TRUE
map(tt, typeof)
#> $marker
#> [1] "double"
#> 
#> $`rcspline.eval(age, inclx = TRUE)`
#> [1] "double"
map(tt, rlang::type_of)
#> $marker
#> [1] "double"
#> 
#> $`rcspline.eval(age, inclx = TRUE)`
#> [1] "double"
map(tt, is.matrix)
#> $marker
#> [1] FALSE
#> 
#> $`rcspline.eval(age, inclx = TRUE)`
#> [1] TRUE

# Should we use this?
map(tt, ~rlang::is_vector(.x) & !is.matrix(.x))
#> $marker
#> [1] TRUE
#> 
#> $`rcspline.eval(age, inclx = TRUE)`
#> [1] FALSE

Created on 2019-12-16 by the reprex package (v0.3.0)

ddsjoberg commented 4 years ago

Something to consider: The model.frame is used to 1. Get the reference level for categorical variables, and 2. To get default labels for variables that have been labelled.

In these edge cases when we cannot match a term to a variable in the model.frame, we could simply assume the variable is continuous (i.e. display on one row), and the label will just be the model term (which should be able to be updated with the label argument). Hmmmm, still need time to think

ddsjoberg commented 4 years ago

This has been resolved in PR #254, BUT we still need to add a unit test checking this is accurately performed so it does not break in the future.