#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)
команду inlapply
? Я попробовал этоFUN = plot(....)
сделать, и у меня ничего не вышло. Я не уверен в поведении этого объекта (если это правильный термин).4.@dc3rd Я ценю, как внимательно вы смотрите на код! Да, точно,
lapply
этоfor
цикл, но реализованный на C, и поэтому намного быстрее. Я добавил правку, чтобы показать, как это будет сделано вfor
цикле R. Этоfunction(x)
предшествует телу так называемой анонимной функции, которую мы определяем впоследствии; без нееplot
вы не узнаете, чтоx
такое и почему вы, вероятно, потерпели неудачу. Смотрите такжеhelp("function")
.