[R] Query on ksmooth(): Theoretical step function vs. plotted diagonal segments
Martin Maechler
m@ech|er @end|ng |rom @t@t@m@th@ethz@ch
Fri Mar 20 09:28:29 CET 2026
>>>>> 송상은
>>>>> on Thu, 19 Mar 2026 23:00:00 +0900 writes:
> Dear R-help members,
> Hello,
> I am studying kernel regression and experimenting with the ksmooth()
> function in R.
> When using a box kernel, the kernel function is an indicator function
> (weight = 1 inside the bandwidth and 0 outside). Based on this definition,
> I expected the Nadaraya–Watson estimator to produce a step-like function:
> the estimate should remain constant while the set of included points is
> unchanged, and then jump when a point enters or leaves the bandwidth window.
> However, when I run the following code using the cars dataset:
> par(mfrow=c(1,1))
> with(cars, {
> plot(speed, dist)
> lines(ksmooth(speed, dist, "normal", bandwidth = 2),
> col = "blue", lwd = 3)
> lines(ksmooth(speed, dist, "box", bandwidth = 2),
> col = "darkorange", lwd = 3)
> })
> legend("topleft", c("Normal Kernel with h=2", "Box Kernel with h=2"),
> lwd = c(2,2),
> col = c("blue","darkorange"), cex = 2)
> the curve produced by the box kernel (dark orange) appears to contain
> diagonal line segments rather than the step-like shape I expected. I have
> attached the resulting plot for reference.
> My understanding is that the theoretical estimator should behave like a
> step function because the kernel weights are either 0 or 1. Therefore, I
> was wondering whether the diagonal segments arise from how ksmooth()
> evaluates the estimator on a grid of x values and then connects those
> points with straight lines for plotting, or if there is another
> implementation detail that explains this behavior.
> Could you please clarify whether this is expected behavior?
Definitely, as Jeff and Rui explained.
As solution e.g. for teaching / illustration (otherwise the box
kernel should *never* be used!), I recommend just to evaluate
the resulting function on a finer grid, e.g., at 1000 instead
of by default 100 points:
## MM: evaluate the curve on a much finer grid, using n.points = 1000 (default was 100)
with(cars, {
plot(speed, dist)
lines(ksmooth(speed, dist, "norm", bandwidth = 2, n.points=1000), col = "blue", lwd = 3)
lines(ksmooth(speed, dist, "box", bandwidth = 2, n.points=1000), col = "darkorange", lwd = 3)
})
legend("topleft", c("Normal Kernel with h=2", "Box Kernel with h=2"),
lwd = 2, col = c("blue","darkorange"), bty="n")
--
Martin
More information about the R-help
mailing list