You seem to be thinking about pspline()
similarly to a cubic regression spline. That's not how it works. It's a simple form of a smoothing spline. This page compares different smoothing methods. This page compares pspline
smoothing and the regression splines implemented by the rcs()
function in the rms
package, in the context of a Cox model.
If you want to specify knot positions between which unpenalized cubic functions are fit, then you are talking about regression splines. The approach of pspline()
is different. It sets up a series of basis functions spaced evenly across the limits of the predictor values and produces a penalized regression coefficient for each of the basis functions.
If you specify a value for df
and don't specify boundary knot locations, then the default nterm
argument is round(2.5*df)
(8 in your example) and knots to join the basis functions are placed according to the following code:
dx <- (Boundary.knots[2] - Boundary.knots[1])/nterm
knots <- c(Boundary.knots[1] + dx * ((-degree):(nterm - 1)),
Boundary.knots[2] + dx * (0:degree))
where the default Boundary.knots[2]
and Boundary.knots[1]
are the limits of the data range and degree
is 3 for a cubic fit.
The multiple coefficients that you see reported are for each of the corresponding basis functions between the knots. Each of those coefficient values, however, is penalized or reduced in magnitude from what it would be in a fully fit model. The result is a less wiggly curve than an unpenalized fit would produce.
The df
argument to pspline()
effectively determines how wiggly the final fit is. That's useful if you have decided to spend a certain number of degrees of freedom on modeling a continuous predictor and prefer the smoothing spline to the regression spline approach. The penalization then results in a number of degrees of freedom that is substantially less than the number of knots. Alternatively, if you specify df = 0
the modeling will find optimal smoothing based on the Akaike Information Criterion.
This page goes into more detail about what a Cox model fit with a pspline()
term reports.