Using splines with WeightIt

I need some help troubleshooting this code. I want to include spline terms using the bs() function in my WeightIt propensity score model but I am getting the following error: Error in terms.formula(new.form) : invalid model formula in ExtractVars

This code worked a couple of weeks ago, but now throws an error. WeightIt has not been updated recently so I am having a hard time understanding what has changed.

Thanks!

require(WeightIt)
#> Loading required package: WeightIt**strong text**
weightit(weight ~ bs(height), data = women, estimand="ATE", method="ps", stabilize=T, include.obj = T)
#> Error: All variables in formula must be variables in data or objects in the global environment.
#> Missing variables: bs(height)

Created on 2020-01-02 by the reprex package (v0.2.1)

bs isn't in the namespace. Plain height works

require(WeightIt)
#> Loading required package: WeightIt
weightit(weight ~ height, data = women, estimand="ATE", method="ps", stabilize=T, include.obj = T)
#> A weightit object
#>  - method: "ps" (propensity score weighting)
#>  - number of obs.: 15
#>  - sampling weights: none
#>  - treatment: continuous
#>  - covariates: height

Created on 2020-01-02 by the reprex package (v0.3.0)

Thanks for your response. bs() is a base function that is supposed to create spline and include spline terms in your model. So yes, height works, but it does not include spline terms for height in my model.

Well it's splines::bs

require(WeightIt)
#> Loading required package: WeightIt
weightit(weight ~ splines::bs(women$height), data = women, estimand="ATE", method="ps", stabilize=T, include.obj = T)
#> Error in terms.formula(new.form): invalid model formula in ExtractVars

Created on 2020-01-02 by the reprex package (v0.3.0)

weightit expects the same formula arguments in the model as glm. The splines::bs(women$height) object looks like

require(WeightIt)
#> Loading required package: WeightIt
str((splines::bs(women$height)))
#>  'bs' num [1:15, 1:3] 0 0.185 0.315 0.397 0.437 ...
#>  - attr(*, "dimnames")=List of 2
#>   ..$ : NULL
#>   ..$ : chr [1:3] "1" "2" "3"
#>  - attr(*, "degree")= int 3
#>  - attr(*, "knots")= num(0) 
#>  - attr(*, "Boundary.knots")= num [1:2] 58 72
#>  - attr(*, "intercept")= logi FALSE

Created on 2020-01-02 by the reprex package (v0.3.0)

not a vector object.

It looks like WeightIt doesn't support terms in the call. For example, https://github.com/ngreifer/WeightIt/blob/e09cb1fa983d6c4870671162121ffa2b7e2882fb/R/SHARED.R#L489 will break for any basis expansion type stuff.

You can use the following hack to get around this:

library(WeightIt)
library(splines)
library(magrittr)

# do the basis expansion ahead of time. this creates a
# data.frame with a matrix column, which we need to expand
women2 <- model.frame(weight ~ bs(height), women)

# not sure the best way to flatten the matrix column into vector columns
# so this is an ugly hack. there's probably a better way to do this
# with recipes.
women3 <- as.data.frame(apply(women2, 2, as.vector)) %>% 
  set_names(c("weight", "b1", "b2", "b3"))

weightit(
  weight ~ b1 + b2 + b3,
  data = women3,
  estimand = "ATE",
  method = "ps",
  stabilize = TRUE,
  include.obj = TRUE
)
#> A weightit object
#>  - method: "ps" (propensity score weighting)
#>  - number of obs.: 15
#>  - sampling weights: none
#>  - treatment: continuous
#>  - covariates: b1, b2, b3

Created on 2020-01-02 by the reprex package (v0.3.0)

I'm not sure what assumptions WeightIt makes or if this will break things down the line.

1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.