我知道对具有多个LHS的线性模型的支持是有限的。但是当可以在“mlm”对象上运行函数时,我希望结果是可靠的。使用rstudent
时,会产生奇怪的结果。这是一个错误还是有其他解释?
在下面的示例中,fittedA
和fittedB
相同,但在rstudent
的情况下,第二列不同。
y <- matrix(rnorm(20), 10, 2)
x <- 1:10
fittedA <- fitted(lm(y ~ x))
fittedB <- cbind(fitted(lm(y[, 1] ~ x)), fitted(lm(y[, 2] ~ x)))
rstudentA <- rstudent(lm(y ~ x))
rstudentB <- cbind(rstudent(lm(y[, 1] ~ x)), rstudent(lm(y[, 2] ~ x)))
答案 0 :(得分:2)
set.seed(0)
y <- matrix(rnorm(20), 10, 2)
x <- 1:10
fit <- lm(y ~ x) ## class: "mlm", "lm"
fit1 <- lm(y[, 1] ~ x) ## class: "lm"
fit2 <- lm(y[, 2] ~ x) ## class: "lm"
rstudent(fit)
# [,1] [,2]
#1 0.74417620 0.89121744
#2 -0.67506054 -0.50275275
#3 0.76297805 -0.74363941
#4 0.71164461 0.01075898
#5 0.03337192 0.03355209
#6 -1.75099724 -0.02701558
#7 -1.05594284 0.56993056
#8 -0.48486883 -0.35286612
#9 -0.23468552 0.79610101
#10 2.90701182 -0.93665406
cbind(rstudent(fit1), rstudent(fit2))
# [,1] [,2]
#1 0.74417620 1.90280959
#2 -0.67506054 -0.92973971
#3 0.76297805 -1.47237918
#4 0.71164461 0.01870820
#5 0.03337192 0.06042497
#6 -1.75099724 -0.04056992
#7 -1.05594284 1.02171222
#8 -0.48486883 -0.64316472
#9 -0.23468552 1.69605079
#10 2.90701182 -1.25676088
如您所见,rstandard(fit)
仅正确返回了第一个响应的结果。
rstudent
在“ mlm”上失败问题是,rstudent
没有“ mlm”方法。
methods(rstudent)
#[1] rstudent.glm* rstudent.lm*
当您调用rstudent(fit)
时,S3方法分派机制将查找rstudent.lm
,因为inherits(fit, "lm")
是TRUE
。不幸的是,stats:::rstudent.lm
没有为“ mlm”模型进行正确的计算。
stats:::rstudent.lm
#function (model, infl = lm.influence(model, do.coef = FALSE),
# res = infl$wt.res, ...)
#{
# res <- res/(infl$sigma * sqrt(1 - infl$hat))
# res[is.infinite(res)] <- NaN
# res
#}
lm.influence
没有为“ mlm”提供正确的sigma
。基础C例程C_influence
仅为{lm}计算sigma
。如果为lm.influence
指定一个“ mlm”,则仅返回第一个响应变量的结果。
## pass in "mlm"
.Call(stats:::C_influence, fit$qr, FALSE, residuals(fit), 10 * .Machine$double.eps)$sigma
# [1] 1.3130265 1.3216357 1.3105706 1.3171621 1.3638689 1.1374385 1.2668101
# [8] 1.3416338 1.3586428 0.9180828
## pass in "lm"
.Call(stats:::C_influence, fit1$qr, FALSE, residuals(fit1), 10 * .Machine$double.eps)$sigma
# [1] 1.3130265 1.3216357 1.3105706 1.3171621 1.3638689 1.1374385 1.2668101
# [8] 1.3416338 1.3586428 0.9180828
对于“ mlm”,显然sigma
应该是矩阵。现在给出了这个不正确的sigma
,由于"/"
(残数)的左侧是一个{矩阵,但右边的东西是向量。
stats:::rstudent.lm
有效地,计算结果仅对于第一个响应变量是正确的;所有其余的响应变量将使用错误的res
。
请注意,文档页面res <- res / (infl$sigma * sqrt(1 - infl$hat))
中列出的几乎所有功能对于“ mlm”都是错误的。他们应该发出警告说“ mlm”方法尚未实现。
sigma
需要在C级别打补丁。完成此操作后,?influence.measures
就可以在“ mlm”上正常工作。
其他功能可以很容易地在R级打补丁,例如lm.influnce
和rstudent.lm
。目前(R 3.5.1)为:
stats:::cooks.distance.lm
,并且可以使用
对其进行修补(通过使用stats:::rstandard
)
stats:::cooks.distance.lm
#function (model, infl = lm.influence(model, do.coef = FALSE),
# res = weighted.residuals(model),
# sd = sqrt(deviance(model)/df.residual(model)),
# hat = infl$hat, ...)
#{
# p <- model$rank
# res <- ((res/(sd * (1 - hat)))^2 * hat)/p
# res[is.infinite(res)] <- NaN
# res
#}
stats:::rstandard.lm
#function (model, infl = lm.influence(model, do.coef = FALSE),
# sd = sqrt(deviance(model)/df.residual(model)), type = c("sd.1",
# "predictive"), ...)
#{
# type <- match.arg(type)
# res <- infl$wt.res/switch(type, sd.1 = sd * sqrt(1 - infl$hat),
# predictive = 1 - infl$hat)
# res[is.infinite(res)] <- NaN
# res
#}
快速测试:
outer
答案 1 :(得分:2)
谢谢@李哲源;另请参阅https://www.r-project.org/bugs.html,以了解如何报告错误……R核心团队更清楚地指出了这些错误。另外,在那里,我们可以给补丁更好的信誉。.
Als注意,R的源代码(尤其是其开发版本)始终可以通过svn(“ subversion”)或https://svn.r-project.org/R/trunk/
下一次,option
和ppx
的源代码都在https://svn.r-project.org/R/trunk/src/library/stats/R/lm.influence.R ....中。您建议通过cooks.distance.lm()
进行的小代码更改就足够了。
非常感谢您进行详尽的分析和提出完善的错误修复程序!