La risposta di @Ronald è la migliore ed è ampiamente applicabile a molti problemi simili (per esempio, c'è una differenza statisticamente significativa tra uomini e donne nella relazione tra peso ed età?). Tuttavia, aggiungerò un'altra soluzione che, pur non essendo quantitativa (non fornisce un valore p ), offre una bella visualizzazione grafica della differenza.
EDIT : secondo questa domanda , sembra che predict.lm
la funzione utilizzata ggplot2
per calcolare gli intervalli di confidenza, non calcoli le bande di confidenza simultanee attorno alla curva di regressione, ma solo le bande di confidenza puntuale. Queste ultime bande non sono quelle giuste per valutare se due modelli lineari montati sono statisticamente diversi, o hanno detto in un altro modo, se potrebbero essere compatibili con lo stesso modello reale o meno. Pertanto, non sono le curve giuste per rispondere alla tua domanda. Dal momento che apparentemente non c'è R incorporato per ottenere bande di confidenza simultanee (strano!), Ho scritto la mia funzione. Ecco qui:
simultaneous_CBs <- function(linear_model, newdata, level = 0.95){
# Working-Hotelling 1 – α confidence bands for the model linear_model
# at points newdata with α = 1 - level
# summary of regression model
lm_summary <- summary(linear_model)
# degrees of freedom
p <- lm_summary$df[1]
# residual degrees of freedom
nmp <-lm_summary$df[2]
# F-distribution
Fvalue <- qf(level,p,nmp)
# multiplier
W <- sqrt(p*Fvalue)
# confidence intervals for the mean response at the new points
CI <- predict(linear_model, newdata, se.fit = TRUE, interval = "confidence",
level = level)
# mean value at new points
Y_h <- CI$fit[,1]
# Working-Hotelling 1 – α confidence bands
LB <- Y_h - W*CI$se.fit
UB <- Y_h + W*CI$se.fit
sim_CB <- data.frame(LowerBound = LB, Mean = Y_h, UpperBound = UB)
}
library(dplyr)
# sample datasets
setosa <- iris %>% filter(Species == "setosa") %>% select(Sepal.Length, Sepal.Width, Species)
virginica <- iris %>% filter(Species == "virginica") %>% select(Sepal.Length, Sepal.Width, Species)
# compute simultaneous confidence bands
# 1. compute linear models
Model <- as.formula(Sepal.Width ~ poly(Sepal.Length,2))
fit1 <- lm(Model, data = setosa)
fit2 <- lm(Model, data = virginica)
# 2. compute new prediction points
npoints <- 100
newdata1 <- with(setosa, data.frame(Sepal.Length =
seq(min(Sepal.Length), max(Sepal.Length), len = npoints )))
newdata2 <- with(virginica, data.frame(Sepal.Length =
seq(min(Sepal.Length), max(Sepal.Length), len = npoints)))
# 3. simultaneous confidence bands
mylevel = 0.95
cc1 <- simultaneous_CBs(fit1, newdata1, level = mylevel)
cc1 <- cc1 %>% mutate(Species = "setosa", Sepal.Length = newdata1$Sepal.Length)
cc2 <- simultaneous_CBs(fit2, newdata2, level = mylevel)
cc2 <- cc2 %>% mutate(Species = "virginica", Sepal.Length = newdata2$Sepal.Length)
# combine datasets
mydata <- rbind(setosa, virginica)
mycc <- rbind(cc1, cc2)
mycc <- mycc %>% rename(Sepal.Width = Mean)
# plot both simultaneous confidence bands and pointwise confidence
# bands, to show the difference
library(ggplot2)
# prepare a plot using dataframe mydata, mapping sepal Length to x,
# sepal width to y, and grouping the data by species
p <- ggplot(data = mydata, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
# add data points
geom_point() +
# add quadratic regression with orthogonal polynomials and 95% pointwise
# confidence intervals
geom_smooth(method ="lm", formula = y ~ poly(x,2)) +
# add 95% simultaneous confidence bands
geom_ribbon(data = mycc, aes(x = Sepal.Length, color = NULL, fill = Species, ymin = LowerBound, ymax = UpperBound),alpha = 0.5)
print(p)
Le bande interne sono quelle calcolate per impostazione predefinita da geom_smooth
: sono bande di confidenza puntuali del 95% attorno alle curve di regressione. Le bande esterne semitrasparenti (grazie per la punta grafica, @Roland) sono invece le bande di confidenza simultanee al 95%. Come puoi vedere, sono più grandi delle bande puntuali, come previsto. Il fatto che le bande di confidenza simultanee delle due curve non si sovrappongano può essere preso come un'indicazione del fatto che la differenza tra i due modelli è statisticamente significativa.
Naturalmente, per un test di ipotesi con un valore p valido , è necessario seguire l'approccio @Roland, ma questo approccio grafico può essere visto come analisi di dati esplorativi. Inoltre, la trama può darci alcune idee aggiuntive. È chiaro che i modelli per i due set di dati sono statisticamente diversi. Ma sembra anche che i modelli a due gradi 1 si adattino ai dati quasi come ai due modelli quadratici. Possiamo facilmente verificare questa ipotesi:
fit_deg1 <- lm(data = mydata, Sepal.Width ~ Species*poly(Sepal.Length,1))
fit_deg2 <- lm(data = mydata, Sepal.Width ~ Species*poly(Sepal.Length,2))
anova(fit_deg1, fit_deg2)
# Analysis of Variance Table
# Model 1: Sepal.Width ~ Species * poly(Sepal.Length, 1)
# Model 2: Sepal.Width ~ Species * poly(Sepal.Length, 2)
# Res.Df RSS Df Sum of Sq F Pr(>F)
# 1 96 7.1895
# 2 94 7.1143 2 0.075221 0.4969 0.61
La differenza tra il modello di grado 1 e il modello di grado 2 non è significativa, quindi possiamo anche usare due regressioni lineari per ciascun set di dati.