Существует очень гибкое решение из @ Kohske / @ beroe , которое также может быть адаптировано для lines
.
Метод заключается в том, что вы оцениваете нулевые значения.
dat.add <- do.call(rbind,
sapply(1:(nrow(dat) - 1), function(i) {
f <- lm(x ~ y, dat[i:(i + 1), ])
if (f$qr$rank < 2) return(NULL)
r <- predict(f, newdata=data.frame(y=0))
if(dat[i, ]$x < r & r < dat[i + 1, ]$x)
return(data.frame(x=r, y=0))
else return(NULL)
})
)
Объединить нули в исходный фрейм данных.
dat <- merge(dat, dat.add, all=TRUE)
Затем создайте пустой график и добавьте сегментированный lines
.
plot(dat, lwd = 2, type="n")
lines(dat[dat$y >= 0, ], col="blue")
lines(dat[dat$y <= 0, ], col="red")
abline(h = 0, col = "grey")
Результат

Обратите внимание, что линии не прерываются на нулевой линии, но abline
в 0
скрывает этот факт, поэтому нас это не должно волновать.
Данные
dat <- structure(list(x = 1:10, y = c(-2, -3, -1, 1, 2, 1, -2, 2, 4,
3)), class = "data.frame", row.names = c(NA, -10L))