#r #plot #linear-regression #interaction
#r #график #линейная регрессия #взаимодействие
Вопрос:
Я пытаюсь предсказать среднюю численность животных, замеченных во время разных фаз Луны (фактор), используя логарифмически преобразованные данные о численности (лучше подходят) и некоторые другие переменные. Оказалось, что лучшая модель (наименьший AIC) включает взаимодействие фазы и продолжительности съемки и облачного покрова (оба непрерывные):
LMoon<-lm(ln~Phase*Duration Clouds, data=abund)
summary(LMoon)
Call:
lm(formula = ln ~ Phase * Duration Clouds, data = abund)
Residuals:
Min 1Q Median 3Q Max
-1.75416 -0.46311 0.09522 0.46591 1.85978
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.382031 0.876865 0.436 0.664125
Phase2 2.130065 1.226305 1.737 0.085851 .
Phase3 1.971060 1.818542 1.084 0.281351
Phase4 0.608043 1.140122 0.533 0.595146
Phase5 4.786674 1.151850 4.156 7.44e-05 ***
Phase6 0.958706 1.046831 0.916 0.362238
Phase7 0.254711 3.425214 0.074 0.940888
Phase8 0.865995 1.043916 0.830 0.409005
Duration 0.069153 0.035407 1.953 0.053952 .
Clouds -0.004259 0.002401 -1.774 0.079494 .
Phase2:Duration -0.087843 0.047818 -1.837 0.069545 .
Phase3:Duration -0.089908 0.069652 -1.291 0.200109
Phase4:Duration -0.005424 0.046675 -0.116 0.907749
Phase5:Duration -0.172016 0.049369 -3.484 0.000768 ***
Phase6:Duration -0.035597 0.041435 -0.859 0.392583
Phase7:Duration 0.024084 0.176773 0.136 0.891939
Phase8:Duration -0.033424 0.042064 -0.795 0.428963
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.7721 on 89 degrees of freedom
Multiple R-squared: 0.3368, Adjusted R-squared: 0.2176
F-statistic: 2.825 on 16 and 89 DF, p-value: 0.0009894
Теперь, из-за этого взаимодействия, мне нужно составить график взаимодействия (CI слишком широк при построении lsmeans).
Я пытался использовать различные функции, упомянутые там, но ни одна из них не работала.
По-видимому, мне нужно рассчитать и построить график вручную, что я и сделал, как это:
intercepts <- c(coef(LMoon)["(Intercept)"],
coef(LMoon)["(Intercept)"] coef(LMoon)["Phase2"],
coef(LMoon)["(Intercept)"] coef(LMoon)["Phase3"],
coef(LMoon)["(Intercept)"] coef(LMoon)["Phase4"],
coef(LMoon)["(Intercept)"] coef(LMoon)["Phase5"],
coef(LMoon)["(Intercept)"] coef(LMoon)["Phase6"],
coef(LMoon)["(Intercept)"] coef(LMoon)["Phase7"],
coef(LMoon)["(Intercept)"] coef(LMoon)["Phase8"])
lines.df <- data.frame(intercepts = intercepts,
slopes = c(coef(LMoon)["Duration"],
coef(LMoon)["Duration"] coef(LMoon)["Phase2:Duration"],
coef(LMoon)["Duration"] coef(LMoon)["Phase3:Duration"],
coef(LMoon)["Duration"] coef(LMoon)["Phase4:Duration"],
coef(LMoon)["Duration"] coef(LMoon)["Phase5:Duration"],
coef(LMoon)["Duration"] coef(LMoon)["Phase6:Duration"],
coef(LMoon)["Duration"] coef(LMoon)["Phase7:Duration"],
coef(LMoon)["Duration"] coef(LMoon)["Phase8:Duration"]),
Phase2 = levels(abund$Phase))
qplot(x = Duration, y = Sp2, color = Phase, data = abund)
geom_abline(aes(intercept = intercepts,
slope = slopes,
color = Phase), data = lines.df)
График, который я получаю, неверен, поскольку значения y находятся в исходном истинном масштабе, но строки основаны на lm, который использует данные, преобразованные в журнал.
количество графиков взаимодействия, продолжительность, фазы Луны
Для обратного преобразования кто-то сказал мне, что в итоге я не получу прямых линий. Вместо того, чтобы использовать abline (), я должен создать набор, например, из 100 новых значений x, которые охватывают диапазон данных о продолжительности, и использовать коэффициенты для вычисления ваших прогнозируемых значений y. Затем постройте их с помощью lines(), и это должно выглядеть как плавная кривая.
И вот тут я заблудился.
Итак, я создал набор новых значений x для диапазона продолжительности опроса (мин. 15 максимум 45 мин): dur2 <- seq(from = 15, to = 45, length.out=100)
Затем, как только я получу эти значения, я должен получить прогнозируемое значение y для каждого значения x, используя коэффициенты моего LM. После этого выполните обратное преобразование значений y в исходный масштаб. А затем, используя значения x и преобразованные обратно значения y, добавьте линии к графику.
Как мне теперь точно получить прогнозируемые значения? Я не могу использовать какой-либо тип / функцию pred, я все это перепробовал. Это просто не работает с моей моделью, поэтому единственный способ — вручную, но я понятия не имею, как это сделать…
Надеюсь, что кто-нибудь сможет мне в этом помочь, я пытался неделями и к настоящему времени в отчаянии, близок к тому, чтобы сдаться.
Приветствия!
PS Здесь данные:
> dput(subset(abund, Phase %in% c("Phase1", "Phase2")))
structure(list(Year = integer(0), Date = structure(integer(0), .Label = c("01/08/2009",
"01/08/2016", "02/07/2019", "02/08/2009", "02/08/2012", "02/08/2016",
"02/09/2007", "03/08/2007", "03/08/2009", "03/08/2014", "03/08/2015",
"04/07/2019", "04/08/2009", "04/08/2013", "05/08/2009", "05/08/2014",
"05/08/2015", "06/07/2008", "06/07/2019", "07/08/2009", "08/07/2010",
"09/07/2010", "09/08/2015", "10/08/2009", "11/08/2009", "12/08/2009",
"13/08/2009", "13/08/2014", "14/08/2009", "14/08/2012", "16/07/2006",
"18/07/2009", "18/08/2015", "19/07/2011", "20/08/2009", "21/07/2011",
"21/09/2009", "22/07/2011", "22/07/2016", "22/07/2017", "23/07/2007",
"23/07/2016", "23/07/2017", "24/07/2017", "25/07/2007", "25/07/2010",
"25/07/2017", "25/08/2016", "26/07/2010", "26/07/2011", "27/07/2006",
"27/07/2011", "27/07/2012", "28/07/2016", "29/06/2019", "29/07/2005",
"29/07/2009", "29/07/2010", "29/07/2016", "29/07/2019", "30/07/2005",
"30/07/2007", "30/07/2016", "30/08/2005", "31/07/2005", "31/07/2009",
"31/07/2014", "31/07/2016"), class = "factor"), NrSurvey = integer(0),
Duration = integer(0), Sp2 = integer(0), Phase = structure(integer(0), .Label = c("1",
"2", "3", "4", "5", "6", "7", "8"), class = "factor"), Clouds = integer(0),
Visibility = integer(0), ln = numeric(0)), row.names = integer(0), class = "data.frame")
Комментарии:
1. tl; dr но смотрите: nature.com/articles/npre.2010.4136.1 почему вы не должны преобразовывать данные подсчета в журнал
2. Это действительно легко сделать с помощью пакета emmeans.
3. @Dylan_Gomes это правда, но у меня нет нулей в моем наборе данных, поскольку я фокусируюсь только на положительных опросах, т.Е. Там, Где были замечены животные. Я просто хочу посмотреть, отличается ли количество животных в зависимости от фаз Луны. Для отсутствия присутствия я использую разные модели
4. @RussLenth не могли бы вы уточнить? Я уже пробовал emmeans раньше, однако CI слишком широк из-за взаимодействия
5. @Cathrin, избавление от нулей также приводит к потере информации, поскольку отсутствие — это информация. Возможно, стоит взглянуть на пуассоновскую или отрицательную биномиальную модель, а не на то, что вы делаете. Но это только мое мнение.
Ответ №1:
Используется predict
для получения прогнозируемых значений. Не вычисляйте вручную.
Используется expand.grid()
для создания фрейма данных всех комбинаций вашей dur2
последовательности и других предикторов со значением (значениями), которые вы хотите отобразить. Что-то вроде этого:
prediction_data = expand.grid(
Duration = dur2,
Phase= unique(abund$Phase),
Clouds = mean(abund$Clouds) # Hold Clouds constant at some value
)
# column names in prediction_data need to match those in the model formula
prediction_data$pred = predict(LMoon, newdata = prediction_data)
prediction_data$pred_orig = exp(prediction_data$pred)
# plot
ggplot(prediction_data, aes(x = Duration, y = pred_orig, color = Phase))
geom_line()
geom_point(data = abund)
Что-то подобное должно сработать.
Еще один хороший вариант — использовать broom::augment
для генерации прогнозов. Это может легко дать стандартные ошибки и остатки для каждой точки прогнозирования.
library(broom)
prediction_data = augment(LMoon, newdata = prediction_data)
Комментарии:
1. Убедитесь
prediction_data
, что у столбца есть имяPhase
, и все должно быть в порядке. Если вы опубликуете воспроизводимую выборку данных (возможноdput(subset(abund, Phase %in% c("Phase1", "Phase2")))
, или, возможно, меньшее подмножество, тогда мы действительно сможем запустить код на чем-то, похожем на ваши данные, что очень полезно для отладки.2. Большое спасибо, это сработало!! — Кроме построения графика, он продолжает выдавать мне ошибку
FUN(X[[i]], ...) : object 'pred_orig' not found
. Однако при запуске только строки ggplot(prediction_data, aes(x = Duration, y = pred_orig)) без geom_line / point() ошибка не возникает. Есть идеи?3. Также заметил, что график пуст. Это не при использовании base = 10 в log() Перед запуском модели и т. Д., Тогда график дает мне, по крайней мере, несколько точек и линий, но все равно не с geom_line / point()
4. Вам нужно будет создать
pred_orig
столбец, как в моем ответе. Понятия не имею о пустом графике, но если вы поделитесь некоторыми примерами данных, я мог бы попытаться взглянуть. Смотрите мой предыдущий комментарий о том, как обмениваться образцами данных.5. Привет, у меня возникли другие проблемы с графиком взаимодействия — с двоичными данными присутствия / отсутствия. График соединяет каждую точку между верхним и нижним пределом, есть идеи, почему это так? Я использовал ваше предложение выше, но это было для подсчета данных. Работа с glm()