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.86
但 coef
的正确答案是 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 平方时,我通常会要求“百分比”。那么相同的公差可能适用于系数。
我建议适当控制系数的大小,以便 digits
和 extol
可以相应地设置。
就我个人而言,我通常以比我向学生要求的精度更高的精度存储 exsolution
。例如,exsolution
可以是 12.345678
,而我只将 extol
设置为 0.01
。这确保当正确答案四舍五入到小数点后两位时,它位于由 exsolution
和 extol
.
确定的正确区间内
有关摘要中系数格式的详细信息:
格式化的确切位置并不明显: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]
}
我正在使用包 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.86
但 coef
的正确答案是 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 平方时,我通常会要求“百分比”。那么相同的公差可能适用于系数。
我建议适当控制系数的大小,以便
digits
和extol
可以相应地设置。就我个人而言,我通常以比我向学生要求的精度更高的精度存储
确定的正确区间内exsolution
。例如,exsolution
可以是12.345678
,而我只将extol
设置为0.01
。这确保当正确答案四舍五入到小数点后两位时,它位于由exsolution
和extol
.
有关摘要中系数格式的详细信息:
格式化的确切位置并不明显:
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] }