我知道如何轻松做到这一点的唯一方法是根据模型在整个范围内进行sqft
预测并绘制预测。没有通用的方法abline
或类似方法。您还可以查看适合这些模型并为您提供绘图基础结构的分段软件包。
通过预测和基本图形执行此操作。首先,一些伪数据:
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)
拟合模型:
mod <- lm(price~sqft+I((sqft-mean(sqft))*Ind), data = DF)
生成一些数据以进行预测和预测:
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))
绘制回归线:
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)
您可以将其编码为一个简单的函数-您只需要前面两个代码块中的步骤-可以代替以下代码使用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)
}
然后:
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)
通过分段包装
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")
对于这些数据,它不会估计处的断点mean(sqft)
,但该包中的plot
和lines
方法可能会帮助您实现比myabline
从拟合lm()
模型中直接为您完成这项工作更通用的功能。
编辑:如果要分段以估计断点的位置,则将'psi'
参数设置为NA
:
mod.s <- segmented(mod2, seg.Z = ~ sqft, psi = NA,
control = seg.control(stop.if.error = FALSE))
然后segmented
将尝试的K = 10
分位数sqft
,K
设置为seg.control()
,默认为10
。查看?seg.control
更多。