【问题标题】:Is there a way to obtain residual plots for all interaction terms?有没有办法获得所有交互项的残差图?
【发布时间】:2021-10-03 21:05:42
【问题描述】:

我正在做一个练习,要求我“将残差与 Y_hat、每个预测变量和每个双因素交互项绘制在单独的图表上。”这是我正在使用的数据集的 sn-p:

> dput(head(Commercial_Properties, 10))
structure(list(Rental_Rates = c(13.5, 12, 10.5, 15, 14, 10.5, 
14, 16.5, 17.5, 16.5), Age = c(1, 14, 16, 4, 11, 15, 2, 1, 1, 
8), Op_Expense_Tax = c(5.02, 8.19, 3, 10.7, 8.97, 9.45, 8, 6.62, 
6.2, 11.78), Vacancy_Rate = c(0.14, 0.27, 0, 0.05, 0.07, 0.24, 
0.19, 0.6, 0, 0.03), Total_Sq_Ft = c(123000, 104079, 39998, 57112, 
60000, 101385, 31300, 248172, 215000, 251015), residuals = c(`1` = -1.03567244005944, 
`2` = -1.51380641405037, `3` = -0.591053402133659, `4` = -0.133568082335235, 
`5` = 0.313283765150399, `6` = -3.18718522392237, `7` = -0.538356748944345, 
`8` = 0.236302385996349, `9` = 1.98922037248654, `10` = 0.105829602747806
)), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"
))

从这里我创建了包含两个因子交互项的正确线性模型:

commercial_properties_lm_two_degree_interaction <- 
  lm(data=Commercial_Properties, 
     formula=Rental_Rates ~ (Age + Op_Expense_Tax + Vacancy_Rate + Total_Sq_Ft)^2)

接下来我希望完成的是不仅绘制线性项的残差,还绘制交互项的残差。我尝试使用car 包中的residualPlots() 函数来完成此操作

library(car)
residualPlots(model=commercial_properties_lm_two_degree_interaction, 
              terms=~ (Age + Op_Expense_Tax + Vacancy_Rate + Total_Sq_Ft)^2)

当以这种方式应用时,输出仅针对线性项生成残差图,它没有绘制任何交互。于是我尝试手动操作,但出现错误:

residualPlots(model=commercial_properties_lm_two_degree_interaction,
              terms=~ Age + Op_Expense_Tax + Vacancy_Rate + Tota_Sq_Ft + 
                Age:Op_Expense_Tax + Age:Vacancy_Rate)

Error in termsToMf(model, terms) : argument 'terms' not interpretable.

现在,如果我完全手动执行操作,我可以得到一个交互图,例如:

with(data=Commercial_Properties, plot(x=Op_Expense_Tax * Vacancy_Rate, y=residuals))

绘制成功。我的问题是,对于相当少量的变量,我确实可以完全手动执行此操作,但是一旦变量的数量开始变大,它就会变得非常乏味。

所以我的问题是,是否有一种方法可以使用 R 中已经创建的函数来制作交互项的残差图,或者我会完全手动完成它还是很可能不得不编写某种循环?

注意,我问的不是部分残差。在我正在使用的文本中,我还没有达到这一点。只是针对残差的简单交互项。

【问题讨论】:

    标签: r plot linear-regression gplots


    【解决方案1】:

    您可以使用'term.labels' 属性执行eval(parse()) 方法。

    使用gsub(':', '*', a[grep(':', a)]) 提取交互项并将: 替换为*,以便对其进行评估。

    a <- attr(terms(commercial_properties_lm_two_degree_interaction), 'term.labels')
    
    op <- par(mfrow=c(2, 3))
    with(Commercial_Properties, 
         lapply(gsub(':', '*', a[grep(':', a)]), function(x)
                plot(eval(parse(text=x)), residuals, xlab=x)))
    par(op)
    

    编辑

    这就是我们在 R 中使用 for 循环的方式(但请参阅下面的 cmets):

    as <- gsub(':', '*', a[grep(':', a)])
    op <- par(mfrow=c(2, 3))
    for (x in as) {
      with(Commercial_Properties, 
           plot(eval(parse(text=x)), residuals, xlab=x)
      )
    }
    par(op)
    

    【讨论】:

    • 我以前从未使用过gsub 函数。我要去看看它。因为我这样做是为了学习更多技术。谢谢你的建议。我刚刚检查了你的个人资料。感谢您提供 R 风格指南的链接。我在做事时总是对最佳实践有疑问。
    • 所以我检查了你的代码以进一步理解它,因为它有一些我没有使用过的功能,但阅读起来会很有用。 lapply 中的代码是这样工作的吗:gsub() 正在我的向量 a 中找到具有 : 的元素,将它们替换为 *,这些是通过 grep() 函数找到的。这是我有点困惑的地方。我们指定function(x),特别是我们将应用plot 函数。要获取 x 轴项,eval 用于获取每个单独交互集的值。 lapply 是不是有点像 for 循环?
    • 我的主要问题是为什么我们在lapply 中使用function(x) 命令?我用FUN = plot(....) 尝试过,但失败了。我不确定该对象(如果这是正确的术语)的行为。
    • @dc3rd 非常感谢您仔细查看代码!没错,lapply for 循环,但是implemented in C,因此要快得多。我添加了一个编辑以显示如何在 R for 循环中完成此操作。 function(x) 位于我们之后定义的所谓匿名函数的主体之前;没有它,plot 将不知道x 是什么,这就是你可能失败的原因。另请参阅help("function")
    猜你喜欢
    • 1970-01-01
    • 2021-05-09
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 2019-12-13
    相关资源
    最近更新 更多