lm R 汇总输出的精度

Precision in summary output of lm R

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

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.86coef 的正确答案是 2726.8605 .

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

我只想这样做:

answers<-coef(m0) %>% format(digits=dsum) %>% as.numeric()

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

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

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

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

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

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

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

    确定的正确区间内

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

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

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

  • 系数不是单独格式化的,而是与相应的标准误差一起格式化的。详细信息取决于 digits、系数和标准误差的大小,以及任何系数是否混叠或恰好为零等。

  • 没有 aliased/zero 系数,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]
    }