Есть ли способ получить остаточные графики для всех условий взаимодействия?

#r #plot #linear-regression #gplots

Вопрос:

Я работаю над упражнением, в котором меня просят «Построить остатки по Y_hat, каждой переменной-предиктору и каждому члену двухфакторного взаимодействия на отдельных графиках». Вот фрагмент набора данных, который я использую:

 > 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)
 

Следующее, чего я надеялся достичь, — это построить графики остатков не только линейных членов, но и членов взаимодействия. Я попытался сделать это, используя residualPlots() функцию в car пакете

 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 для создания остаточных графиков условий взаимодействия, или мне придется делать это полностью вручную или, скорее всего, придется написать какой-то цикл ?

Обратите внимание, я не спрашиваю о частичных остатках. Я еще не дошел до этого пункта в своем тексте, который использую. Просто простые условия взаимодействия с остатками.

Ответ №1:

Вы могли бы eval(parse()) применить подход, используя 'term.labels' атрибут.

С помощью 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)
 

введите описание изображения здесь

Редактировать

Вот как мы бы сделали это с for циклом в R (но см. Комментарии ниже):

 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)
 

Комментарии:

1. Я никогда раньше не использовал эту gsub функцию. Я собираюсь взглянуть на это. Так как я делаю это, чтобы изучить больше техник. Спасибо за предложение. и я только что проверил твой профиль. Спасибо за ссылку на руководство по стилю R. У меня всегда возникают вопросы о лучших практиках, когда я что-то делаю.

2. Поэтому я просмотрел ваш фрагмент кода, чтобы понять его немного лучше, так как в нем были некоторые функции, которые я не использовал, но чтение будет полезно. Вот как lapply работает код: gsub() это поиск элементов в моем векторе a , которые : заменяют их * , они были найдены с помощью grep() функции. Вот тут я немного запутался. Мы указываем function(x) , в частности, мы собираемся применить эту plot функцию. Чтобы получить термины по оси x, eval используется для получения значений для каждого отдельного набора взаимодействий. Так это lapply что-то вроде for петли?

3. мой главный вопрос заключается в том, почему мы используем function(x) команду in lapply ? Я попробовал это FUN = plot(....) сделать, и у меня ничего не вышло. Я не уверен в поведении этого объекта (если это правильный термин).

4.@dc3rd Я ценю, как внимательно вы смотрите на код! Да, точно, lapply это for цикл, но реализованный на C, и поэтому намного быстрее. Я добавил правку, чтобы показать, как это будет сделано в for цикле R. Это function(x) предшествует телу так называемой анонимной функции, которую мы определяем впоследствии; без нее plot вы не узнаете, что x такое и почему вы, вероятно, потерпели неудачу. Смотрите также help("function") .