Skip to content
Prev 4875 / 5632 Next

[R-meta] Restricted cubic spline behaviour in moderator variable

Dear Wolfgang,

Thank you for your quick reply. You are right this is to do with the NA values, thank you. Those subtle NA differences ever so slightly affected knot position. That wouldn?t be an issue but as you point out, we are then using a different knot when using  attr(rcs(model.matrix(res.rcs)[,2], 4), "parms")

That alone didn?t fully explain my very aberrant plot that I saw. I tried playing around with subtle changes to knot positions (e.g. moving + - 1) and that to the naked eye actually made almost no change. The differences in the plots were because:

predict(model1,  newmods=rcspline.eval(seq(1,100, length = 100), knots, inclx=TRUE))) was using knot positions that were slightly different position to those that were parameterised in the model (because of how I incorrectly attained them), but in the predict/plot calculation this then resulted in stranger predicted points. Hence strange tail.

I guess I didn?t think of this, as when manually providing the knots, and then using the same predict and plot before, there obviously wasn?t any difference as they were based on exactly the same knot positions.

Thanks for your help here, I was going to resort to manually providing knots as per Harrell, 2015 recommendations (which is what rcs does?), but this will save some hassle.

Thanks
Mick
On 31 Aug 2023, at 18:21, Viechtbauer, Wolfgang (NP) <wolfgang.viechtbauer at maastrichtuniversity.nl<mailto:wolfgang.viechtbauer at maastrichtuniversity.nl>> wrote:
Dear Mick,

This might have to do with missing values. In the example on the metafor website (https://www.metafor-project.org/doku.php/tips:non_linear_meta_regression<https://www.metafor-project.org/doku.php/tips:non_linear_meta_regression>), both of these lead to the exact same results:

res.rcs <- rma(yi, vi, mods = ~ rcs(xi, 4), data=dat)
res.rcs

knots <- attr(rcs(model.matrix(res.rcs)[,2], 4), "parms")
knots

res.rcs <- rma(yi, vi, mods = ~ rcs(xi, knots), data=dat)
res.rcs

But let's make some of the yi values missing:

dat$yi[1:10] <- NA

Then rerunning the code above will lead to somewhat different results.

This happens because:

rcs(dat$xi, 4)

is actually based on the entire dataset, while

attr(rcs(model.matrix(res.rcs)[,2], 4), "parms")

uses only the rows actually included in the analysis (i.e., removing the first 10 rows).

If you use:

knots <- attr(rcs(dat$xi, 4), "parms")

then

res.rcs <- rma(yi, vi, mods = ~ rcs(xi, knots), data=dat)
res.rcs

will give the same results again.

I have changed the code in the example to use 'knots <- attr(rcs(dat$xi, 4), "parms")' as this is more accurate as to what is happening (even though it makes no difference in the example on the website since there are no missing values). Also, I've expanded the first footnote which gives a hint in this direction.

It would be nice if you could confirm that this solves the issue. If not, we will have to go digging deeper.

Best,
Wolfgang
La Trobe University | TEQSA PRV12132 - Australian University | CRICOS Provider 00115M