【问题标题】:Displaying a broom::tidy tibble as a printed summary table将 broom::tidy tibble 显示为打印的汇总表
【发布时间】:2021-05-07 06:50:18
【问题描述】:

我有一个看起来很奇怪的问题(但要详细说明我为什么要问 很快就会清楚)。

考虑在R中拟合一个线性模型,如下:

lm_fit <- lm(mpg ~ cyl+disp, data = mtcars).

现在假设我们生成一个整洁的tibble(命名为out_summ) 我们使用惊人的broom 包的合身性总结如下:

out_summ <- broom::tidy(lm_fit)
out_summ
#> # A tibble: 3 x 5
#>   term        estimate std.error statistic  p.value
#>   <chr>          <dbl>     <dbl>     <dbl>    <dbl>
#> 1 (Intercept)  34.7       2.55       13.6  4.02e-14
#> 2 cyl          -1.59      0.712      -2.23 3.37e- 2
#> 3 disp         -0.0206    0.0103     -2.01 5.42e- 2

reprex package (v0.3.0) 于 2021-02-02 创建

现在考虑打印lm_fit 对象的摘要 到控制台如下:

summary(lm_fit)
#> 
#> Call:
#> lm(formula = mpg ~ cyl + disp, data = mtcars)
#> 
#> Residuals:
#>     Min      1Q  Median      3Q     Max 
#> -4.4213 -2.1722 -0.6362  1.1899  7.0516 
#> 
#> Coefficients:
#>             Estimate Std. Error t value Pr(>|t|)    
#> (Intercept) 34.66099    2.54700  13.609 4.02e-14 ***
#> cyl         -1.58728    0.71184  -2.230   0.0337 *  
#> disp        -0.02058    0.01026  -2.007   0.0542 .  
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> Residual standard error: 3.055 on 29 degrees of freedom
#> Multiple R-squared:  0.7596, Adjusted R-squared:  0.743 
#> F-statistic: 45.81 on 2 and 29 DF,  p-value: 1.058e-09

reprex package (v0.3.0) 于 2021-02-02 创建

现在,我的问题是 lm_fit 对象和整洁的 out_summ tibble 作为输入,是否可以编写一个函数来轻松重现 打印如上所示的summary(lm_fit) 表?

我查看了 getAnywhere(print.summary.lm)lm 汇总函数 这很复杂。 从某种意义上说,它来源单个列并手动 使用cat() 调整间距以进行漂亮的打印。因此,鉴于整洁的小标题, 这可以很容易地进行逆向工程吗?

动机:我正在开发一个类似于lm的统计建模对象, 但是我们从一开始就使用整洁的tibble 格式。我们还是愿意 为我们的对象添加一个汇总方法。这将采用我们整洁的tibble 格式 并使用summary(lm_fit) 输出样式的格式打印出来 更多。也就是说,我们不想只打印 tibble,而不先制作 它看起来像经典的汇总表格式。

实现这一点的任何帮助,希望代码最少(考虑到整洁的输入), 将不胜感激。

【问题讨论】:

  • summary.lm 的源代码(第 261 行:github.com/SurajGupta/r-source/blob/master/src/library/stats/R/…)显示您可以仅从 lm.fit 对象生成汇总表所需的所有输出(即您不需要小标题创建你的输出)。您是否有理由无法调整此代码以适合您的“lm-like”对象?
  • @jared_mamrot - 谢谢。正如我上面的代码中提到的,您链接到的代码与我上面提到的getAnywhere(print.summary.lm) 相同。我在这里使用lm 作为类比。基本上在我创建的新统计建模对象(如lm,但不同)中,我的所有输出都已经采用整洁的小标题格式。我现在还想为我的新对象创建一个摘要查找表。但我已经有了一个小标题。所以这种情况就像使用来自lm 对象的整洁的小标题输出对lm 进行逆向工程。然后我会将此代码应用于我的设置。这说明清楚了吗?
  • 所以我的问题是,我们如何使用手动和复杂的嵌套cat() 语句轻松地从tibble 转到print.summary.lm 源代码?如您所见,脚本是非常手动构建的。我在问是否有一种优雅的方法可以直接从tibble 输出中以更简洁的方式(使用正确的列间距等)获取此汇总表。如果它有帮助,作为一个思想实验,假设lm 是用broom::tidy 汇总属性编写的。有人要求使用这个整洁的输出为lm 生成摘要输出,你会怎么做?
  • 啊-这更有意义-我会调查一下
  • 感谢您对@jared_mamrot 的关注。我应该澄清一下 - 我最感兴趣的是漂亮地打印摘要输出的系数部分(这是broom::tidy 给你的),但表格的其余部分也很高兴看到构造:)

标签: r lm broom


【解决方案1】:

不知道如何在不使用 lm_fit 对象(或等效对象)的情况下填写汇总表的其余部分,但也许这些“第一步”会有所帮助。

library(tidyverse)

lm_fit <- lm(mpg ~ cyl+disp, data = mtcars)

summarise_lm_like_object <- function(lm_fit){
  out_summ <- broom::tidy(lm_fit) %>%
    mutate(sig = ifelse(p.value <= 0.001, "***",
                        ifelse(p.value <= 0.01, "**",
                               ifelse(p.value <= 0.05, "*", ".")))) %>% 
    rename("Estimate" = estimate,
           "Std. Error" = std.error,
           "t value" = statistic,
           "Pr(>|t|)" = p.value,
           "Significance" = sig)
  
  print.data.frame(out_summ, row.names = FALSE)
  cat("---\n")
  cat("Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1")
}

summarise_lm_like_object(lm_fit)
#>         term    Estimate Std. Error   t value     Pr(>|t|) Significance
#>  (Intercept) 34.66099474 2.54700388 13.608536 4.022869e-14          ***
#>          cyl -1.58727681 0.71184427 -2.229809 3.366495e-02            *
#>         disp -0.02058363 0.01025748 -2.006696 5.418572e-02            .
#> ---
#> Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

reprex package (v1.0.0) 于 2021 年 2 月 3 日创建

【讨论】:

  • 这太棒了!我认为这里的主要功能是print.data.frame,它做了很多繁重的 tibble 打印提升,以提供漂亮的摘要输出。这是我不想手动实现的主要功能。感谢您分享此代码。非常感谢!
  • 听起来这就是你想要做的——不客气——好问题
猜你喜欢
  • 2019-08-10
  • 2019-11-16
  • 1970-01-01
  • 2018-09-14
  • 1970-01-01
  • 2020-11-17
  • 2021-12-29
相关资源
最近更新 更多