【问题标题】:Precision in summary output of lm Rlm R 的汇总输出精度
【发布时间】:2021-08-04 17:05:07
【问题描述】:

我正在使用包 r-exams 进行一些练习,其中我打印了来自 lm 对象的摘要并询问学生诸如“这是截距的估计值”之类的问题。这个想法是学生复制摘要输出的值并将该值用作正确答案。这里的问题是我使用来自coef() 函数的值作为正确答案,但这不是一个好主意,因为这些值的精度与summary 输出中显示的值的精度完全不同。这是一个例子:

set.seed(123)
library(tidyverse)
## DATA GENERATION
xbreaks<-c(runif(1,4,4.8),runif(1,6,6.9),runif(1,7.8,8.5),runif(1,9,10))
ybreaks<-c(runif(1,500,1000),runif(1,1800,4000),runif(1,200,800))

b11<-(ybreaks[2]-ybreaks[1])/(xbreaks[2]-xbreaks[1])
b10<-ybreaks[1]-b11*xbreaks[1]

b31<-(ybreaks[3]-ybreaks[2])/(xbreaks[4]-xbreaks[3])
b30<-ybreaks[2]-b31*xbreaks[3]
points_df<-data.frame(x=xbreaks,y=ybreaks[c(1,2,2,3)])

n<-rpois(3,120)

x1<-runif(n[1],xbreaks[1],xbreaks[2])
x2<-runif(n[2],xbreaks[2],xbreaks[3])
x3<-runif(n[3],xbreaks[3],xbreaks[4])

y<-c(b10+b11*x1+rnorm(n[1],0,200),
     ybreaks[2]+rnorm(n[2],0,200),
     b30+b31*x3+rnorm(n[3],0,200))

z0_aw<-data.frame(ph=c(x1,x2,x3),UFC=y,case=factor(c(rep(1,n[1]),rep(2,n[2]),rep(3,n[3]))))
mean_x<-z0_aw$ph%>% mean %>% round(2)
caserng<-sample(1:4,1)
modrng<-sample(1:2,1)
if(caserng!=4){
  z0_aw<-z0_aw[z0_aw$case == caserng,]
}

if(modrng==1){
  m0<-lm(UFC~ph,data=z0_aw)
}else{
  cl <- call("lm", formula = UFC ~ I(ph - mean_x), data = as.name("z0_aw"))
  cl$formula[[3]][[2]][[3]] <- mean_x
  m0<-eval(cl)
}

summary(m0)
#> 
#> Call:
#> lm(formula = UFC ~ I(ph - 7.2), data = z0_aw)
#> 
#> Residuals:
#>     Min      1Q  Median      3Q     Max 
#> -555.53 -121.98    5.46  115.38  457.08 
#> 
#> Coefficients:
#>             Estimate Std. Error t value Pr(>|t|)    
#> (Intercept)  2726.86      57.33   47.57   <2e-16 ***
#> I(ph - 7.2)  -840.05      31.46  -26.70   <2e-16 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> Residual standard error: 182.7 on 116 degrees of freedom
#> Multiple R-squared:  0.8601, Adjusted R-squared:  0.8589 
#> F-statistic: 713.1 on 1 and 116 DF,  p-value: < 2.2e-16

coef(m0)
#> (Intercept) I(ph - 7.2) 
#>   2726.8605   -840.0515

由 reprex package (v2.0.0) 于 2021-05-14 创建

假设设置了r-exams中的extol: 0.0001,要求学生给出截距的估计值。学生会得到错误答案,因为他会回答2726.86,但coef 的正确答案是2726.8605。

可以看出,summary 的输出使用 2 位小数,而coef() 的值具有更高的精度。我想知道为了将相同的格式应用于coef() 生成的值,汇总使用了多少小数。这将确保学生提供的答案与summary 输出的答案相同。

我只想这样做:

answers&lt;-coef(m0) %&gt;% format(digits=dsum) %&gt;% as.numeric()

其中dsum 是摘要输出也使用的位数。

注意:需要保留 4 位小数的精度,因为我还向学生询问了同一 summary 输出中提供的 R-squared 值,因此设置 extol: 0.01 不是一个好主意。此外,问题是随机产生的,估计系数的大小会发生变化,正如我所指出的,这与summary 输出中使用的精度直接相关。

【问题讨论】:

  • print(summary(m0), digits=6) 在Estimate 列中显示2726.8605。它默认转到getOption("digits")-3(来自?summary.lm),因此您可以使用options(digits=9); summary(m0);获得相同的效果。
  • 对于这种情况,如果我这样做 max(3, getOption("digits") – 3) 我得到 4,但显然输出在估计列中使用 2 位数字。如果我这样做 print(summary(m0), digits=6) 然后估计列现在得到 4 位数,但 R-squared 现在得到 6 位数。我真的不明白这是怎么回事。
  • 不幸的是,它的应用相当普遍。我相信它并不是一个完美的报告格式,而是对模型的快速总结,以了解下一步的发展方向。这通常用作 报告格式,通常还可以,但我相信每个人在各个方面(小数、星号等)都有自己的偏好,并添加 print 参数以自定义数字摘要的每一个组成部分似乎都可能过度选择。
  • 长话短说,我很同情你在这里的学术问题,但我认为向学生提出的问题需要明确地说出类似“精度必须为0.0001,你可以需要coef 来获得要求的精度”。或者您应该考虑接受2726.86 作为可接受的答案。
  • 我记得在理解我的学生作业的“所需精度”时遇到了类似的问题(当我教书时)。对一些人来说,精度和有效数字的概念不清楚,需要加强;一旦完成,那么有必要提供辅助方法的指导,以达到 R 中对象所需的精度。

标签: r precision lm summary r-exams


【解决方案1】:

R/exams 中此类问题的一些有用信息:

  • extol 也可以是一个向量,这样您就可以为系数和 R 平方等设置不同的容差。

  • 不过,当询问 R 平方时,我通常会询问“百分比”。那么相同的公差可能适用于系数。

  • 我建议适当控制系数的大小,以便可以相应地设置digits 和extol。

  • 就我个人而言,我通常以比学生要求的更高的精度存储exsolution。例如,exsolution 可能是12.345678,而我只将extol 设置为0.01。这样可以确保当正确答案四舍五入到小数点后两位时,它在exsolution 和extol 确定的正确区间内。

摘要中系数格式的详细信息:

  • 格式化发生的确切位置并不明显:lm 对象的summary() 方法返回一个类summary.lm 的对象,该对象有自己的print() 方法,该方法又调用printCoefmat()。后者是执行实际格式化的函数。

  • 在这些函数中设置digits 时,它控制有效数字的数量,而不是小数位的数量。当系数变得相对较大(例如,数千或更多)时,这一点尤其重要。

  • 系数不是单独格式化的,而是与相应的标准误差联合格式化的。细节取决于digits、系数和标准误差的大小,以及任何系数是否有别名或完全为零等。

  • 没有别名/零系数,summary(m0) 的格式可以使用format_coef(m0) 复制,定义如下。这基本上是来自printCoefmat() 的简化代码。

    format_coef <- function(object, digits = max(3L, getOption("digits") - 2L)) {
      coef_se <- summary(object)$coefficients[, 1L:2L]
      digmin <- 1L + floor(log10(range(abs(coef_se))))
      format(round(coef_se, max(1L, digits - digmin)), digits = digits)[, 1L]
    }
    

【讨论】:

  • extol 也可以是extype: cloze 问题中的向量吗?我应该如何定义该向量?像extol: c(.01,.01,.0001) 这样的东西会给出一些警告。我有 8 个问题,其中只有 3 个是数字。
  • 与其他字段一样:exsolution: 1.23|4.56 和 extol: 0.01|0.0001。 extol 的长度应该与exsolution 的长度相同,并且只填写您需要的元素。
  • 您能解决这些问题吗?如果是这样,最好接受我的答案或自己发布更完整的答案。然后问题将在 StackOverflow 上显示为已解决。如果您仍无法解决问题,请完善问题以便我们找到答案。
  • exsolution 作为向量确实改善了这种情况,但在某些情况下,即使使用 format(coef(m0),digits=xxx),摘要输出也与从 coef 获得的输出不同。当coef 达到数千个数量级时,这些情况是相关的。对我来说,实现与 summary 打印的完全相同的数字并以一致的方式将其存储在 R 对象中仍然是一个悬而未决的问题。
  • 好的,我已经扩展了我的答案并将其分为 R/exams-specific 和 summary.lm-specific 方面。此外,我还追踪了摘要中系数的格式。我希望答案涵盖现在与您相关的所有方面。
猜你喜欢
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多