La única forma en que sé cómo hacer esto fácilmente es predecir a partir del modelo a través del rango sqfty trazar las predicciones. No hay una forma general con ablineo similar. También puede echar un vistazo al paquete segmentado que se ajustará a estos modelos y le proporcionará la infraestructura de trazado.
Hacer esto a través de predicciones y gráficos básicos. Primero, algunos datos ficticios:
set.seed(1)
sqft <- runif(100)
sqft <- ifelse((tmp <- sqft > mean(sqft)), 1, 0) + rnorm(100, sd = 0.5)
price <- 2 + 2.5 * sqft
price <- ifelse(tmp, price, 0) + rnorm(100, sd = 0.6)
DF <- data.frame(sqft = sqft, price = price,
Ind = ifelse(sqft > mean(sqft), 1, 0))
rm(price, sqft)
plot(price ~ sqft, data = DF)
Adaptarse al modelo:
mod <- lm(price~sqft+I((sqft-mean(sqft))*Ind), data = DF)
Genere algunos datos para predecir y predecir:
m.sqft <- with(DF, mean(sqft))
pDF <- with(DF, data.frame(sqft = seq(min(sqft), max(sqft), length = 200)))
pDF <- within(pDF, Ind <- ifelse(sqft > m.sqft, 1, 0))
pDF <- within(pDF, price <- predict(mod, newdata = pDF))
Trace las líneas de regresión:
ylim <- range(pDF$price, DF$price)
xlim <- range(pDF$sqft, DF$sqft)
plot(price ~ sqft, data = DF, ylim = ylim, xlim = xlim)
lines(price ~ sqft, data = pDF, subset = Ind > 0, col = "red", lwd = 2)
lines(price ~ sqft, data = pDF, subset = Ind < 1, col = "red", lwd = 2)
Puede codificar esto en una función simple: solo necesita los pasos en los dos fragmentos de código anteriores, que puede usar en lugar de abline:
myabline <- function(model, data, ...) {
m.sqft <- with(data, mean(sqft))
pDF <- with(data, data.frame(sqft = seq(min(sqft), max(sqft),
length = 200)))
pDF <- within(pDF, Ind <- ifelse(sqft > m.sqft, 1, 0))
pDF <- within(pDF, price <- predict(mod, newdata = pDF))
lines(price ~ sqft, data = pDF, subset = Ind > 0, ...)
lines(price ~ sqft, data = pDF, subset = Ind < 1, ...)
invisible(model)
}
Entonces:
ylim <- range(pDF$price, DF$price)
xlim <- range(pDF$sqft, DF$sqft)
plot(price ~ sqft, data = DF, ylim = ylim, xlim = xlim)
myabline(mod, DF, col = "red", lwd = 2)
A través del paquete segmentado
require(segmented)
mod2 <- lm(price ~ sqft, data = DF)
mod.s <- segmented(mod2, seg.Z = ~ sqft, psi = 0.5,
control = seg.control(stop.if.error = FALSE))
plot(price ~ sqft, data = DF)
plot(mod.s, add = TRUE)
lines(mod.s, col = "red")
Con estos datos no se estima el punto de interrupción mean(sqft), pero los métodos ploty linesen ese paquete pueden ayudarlo a implementar algo más genérico que myablinehacer este trabajo directamente desde el lm()modelo ajustado .
Editar: si desea segmentar para estimar la ubicación del punto de interrupción, configure el 'psi'argumento en NA:
mod.s <- segmented(mod2, seg.Z = ~ sqft, psi = NA,
control = seg.control(stop.if.error = FALSE))
Luego segmentedintentará K = 10cuantiles de sqft, con Kser establecido seg.control()y que por defecto es 10. Mira ?seg.controlpara más.
segmentedcomando.seq.Zcon una fórmula unilateral de las variables que tienen una relación segmentada con la respuesta. Edité mi respuesta para incluirseq.Z = ~ sqfty agregué una nota sobre cómosegmentedelegir valorespsipara usted.