如何在我*不*在 lm 调用本身中使用的 R 中为 lm() 保留 fit$model 中的变量?

How to keep a variable in fit$model for lm() in R that I'm *not* using within the lm call itself?

我希望能够在 适合模型后 索引我的模型。 说我有

df <- data.frame(a = c(1,2,3), 
                 b = c(2,3,1000), 
                 country = c("Malawi", "USA","UK"))

那么,我运行:

fit<-lm(a~b,data=df)

我的结果 fit$model 不再有“国家/地区”变量,因此很难执行

  • 运行 回归,然后删除某些国家/地区作为稳健性 测试。
  • 运行回归然后找出哪些国家是 异常值。

我知道有 'hacks' 围绕这个使用行索引,但我经常发现自己进一步子集原始数据集,我害怕跟踪行索引。

例如从上面的示例中,我看到英国是一个异常值。

所以,我有两个选择:

lm(a~b,data=fit$model[-3,])
lm(a~b,data=df[df$country!="UK",])

第二个选项对我来说更清楚,但是因为 R 中的汇总统计和测试(例如 cook 的距离)只给我行 index,我最终不得不做第一个选项比我想要的多得多。这在我试图测试对异常值或杠杆数据的稳健性并且还想知道这些数据是哪些国家(或其他变量)的大型面板数据集中变得特别乏味。

理想情况下,我想要一个选项来执行类似

的操作
lm(a~b,data=fit$model[fit$model$country!="UK",])

求助,万分感谢!

我假设问题是从 lm 模型中识别原始数据框的行,该模型是 运行 在那些行的子集上 运行 是在不使用所有列的情况下执行。

关于问题中行名称的特征,我不会认为它们的使用是负面的。行名是每个数据框的固有部分,用于标识行。如果您确定具有案例名称的行,这些案例名称将由许多函数显示,包括 case.names(fm)、model.frame(fm)、model.matrix(fm)、cooks.distance(fm)、hatvalues(fm)、influence(fm)、plot(fm) 等,因此非常希望使用它们。这确实是该软件旨在工作的方式,因此强烈建议使用案例名称方法来简化一切。

1) 因此,如果国家/地区名称是案例的唯一标识符,那么只需将它们分配给行名称,即可将它们作为案例名称进行维护。我们省略了 USA 以使示例更难,因为它不像 UK 那样出现在最后,如果我们使用 UK 可能只会给出前两个案例名称无论如何。

df <- data.frame(a = c(1,2,3),  b = c(2,3,1000), country = c("Malawi", "USA","UK"))

rownames(df) <- df$country

fm <- lm(a ~ b, df)
fm2 <- update(fm, subset = country != "USA")  # omit USA
# or:  update(fm, subset = case.names(fm) != "USA")

case.names(fm2)
## [1] "Malawi" "UK"    

2) 尽管 (1) 似乎更可取,但即使我们不将国家列分配给行名称,另一种可行的可能性是在原始数据框:

df <- data.frame(a = c(1,2,3),  b = c(2,3,1000), country = c("Malawi", "USA","UK"))

fm <- lm(a ~ b, df)
fm2 <- update(fm, subset = country != "USA")  # omit USA

df[ case.names(fm2), ]
##   a    b country
## 1 1    2  Malawi
## 3 3 1000      UK

或作为函数:

# first arg is lm object
# second arg is full data frame - data frame used in lm call if unspecified
# third arg is envir where full data frame stored - current envir if unspecified
extractData <- function(mod, data, envir = parent.frame()) {
  if (missing(data)) data <- eval(mod$call$data, envir)
  data[ case.names(mod), ]
}

# test

extractData(fm2)
##   a    b country
## 1 1    2  Malawi
## 3 3 1000      UK