Reply to a re-edited question
The default bandwidth for ksmooth() is 0.5:
ksmooth(x, y, kernel = c("box", "normal"), bandwidth = 0.5, range.x = range(x), n.points = max(100L, length(x)), x.points)
For time series data with a delay of 1, this means that in the vicinity (i-0.5, i+0.5) there will be no other speed data, for the time t = i , except for speed[i] . As a result, the local weighted value is not satisfied!
You need to choose a large bandwidth. For example, if we hope to average over 20 values, we should set bandwidth = 10 (not 20, since it is two-way). This is what we get:
fit <- ksmooth(vehicle$t, vehicle$speed, bandwidth = 10) plot(vehicle, cex = 0.5) lines(fit,col=2,lwd = 2)

Smoothness selection
One problem with ksmooth() is that you have to set bandwidth yourself. You can see that this parameter greatly changes the set curve. A large bandwidth makes the curve smooth, but far from the data; while the small bandwidth is inverse.
Is there an optimal bandwidth ? Is there any way to choose the best?
Yes, use sm.regression() from the sm package, with a cross-validation method to select the bandwidth.
fit <- sm.regression(vehicle$t, vehicle$speed, method = "cv", eval.points = 0:1035)

You can check that fit$h is 18.7.
Another approach
Perhaps you think sm.regression() oversaturated with your data? Well, use loess() , or my favorite: smooth.spline() .
I had an answer:
Here I would demonstrate the use of smooth.spline() :
fit <- smooth.spline(vehicle$t, vehicle$speed, all.knots = TRUE, control.spar = list(low = -2, hight = 2)) # Call: # smooth.spline(x = vehicle$t, y = vehicle$speed, all.knots = TRUE, # control.spar = list(low = -2, hight = 2)) # Smoothing Parameter spar= 0.2519922 lambda= 4.379673e-11 (14 iterations) # Equivalent Degrees of Freedom (Df): 736.0882 # Penalized Criterion: 3.356859 # GCV: 0.03866391 plot(vehicle, cex = 0.5) lines(fit$x, fit$y, col = 2, lwd = 2)

Or using its relational version of the spline:
fit <- smooth.spline(vehicle$t, vehicle$speed, nknots = 200) plot(vehicle, cex = 0.5) lines(fit$x, fit$y, col = 2, lwd = 2)

You really need to read my first link above to understand why I use control.spar in the first case, and without it in the second case.
More powerful package
I definitely recommend mgcv . I have several answers regarding mgcv , but I do not want to suppress you. Therefore, I will not redistribute here. Learn to make good use of ksmooth() , smooth.spline() and loess() . In the future, when you encounter a more complex problem, return to the stack overflow and ask for help!