Home > OS >  R telling me vectors are not vectors when I map function that includes grf::causal_forest()
R telling me vectors are not vectors when I map function that includes grf::causal_forest()

Time:11-18

I want to pass a vector of column names to purrr::map() and iteratively pass them to the grf::causal_forest() function. In attempting this, i get an error that the values i'm passing to causal_forest() are not vectors (which is required) even though they definitely are.

For example, say I have this df

n <- 500
p <- 5
X <- matrix(rnorm(n * p), n, p)
W <- rbinom(n, 1, 0.5)
Y1 <- pmax(X[, 1], 0) * W   X[, 2]   pmin(X[, 3], 0)   rnorm(n)
Y2 <- pmax(X[, 1], 0) * W   X[, 2]   pmin(X[, 3], 0)   rnorm(n)
Y3 <- pmax(X[, 1], 0) * W   X[, 2]   pmin(X[, 3], 0)   rnorm(n)
df <- data.frame(Y1, Y2, Y3, W, X)

head(df)

          Y1           Y2          Y3 W           X1         X2          X3          X4          X5
1  0.5457143  1.933581483  2.38474639 1 -0.788463384  0.9146194  0.73684926 -0.51268651 -0.53317046
2  0.9640213 -1.098133573  1.15639726 1  0.008873619  1.1513535 -1.09108874  0.10308198  1.46560149
3  0.8839862  0.005357524  1.26430215 1  1.588380125 -0.9261196  0.35219255  0.81017210 -1.86847771
4  0.1424579 -0.783984941 -0.01038922 0  2.391068797  0.3080699 -0.94651780  1.92707015  0.42646239
5  0.1771250  0.484711614 -1.95481918 1  0.058835623  0.2541232 -0.05696465  0.01781394 -0.07254417
6 -1.8144585 -1.972902090 -1.47101855 1 -0.518724916 -1.1474859  0.94850272  0.80635703  0.72156403

Where Y* are the dependent variables, X* is the covariate matrix, and W is a binary treatment indicator. I can estimate the model with just a single value of Y* like so

library(grf)

c_forest <- causal_forest(
  X = X, 
  Y = df$Y1, 
  W = df$W)

ate_c_forest <- average_treatment_effect(
  c_forest, 
  target.sample = "overlap")

ate_c_forest

  estimate    std.err 
0.12262543 0.09578717 

But I want to iterate over each value of Y1, Y2, and Y3 using map(), then extract the estimate and std.err for the output of each call to average_treatment_effect(), and put these inside a tibble. So I wrote this small function

Y_n <- c("Y1", "Y2", "Y3")
names(Y_n) <- Y_n

grf_fcn <- function(.x){
  Y <- df$.x
  W <- df$W
  
  c_forest <- causal_forest(
    X = X,
    W = W,
    Y = Y)
  
  ate_c_forest <- average_treatment_effect(
    c_forest, 
    target.sample = "overlap")
}

## call function
library(purrr)

grf_results <- purrr::map(
  .x = tidyselect::all_of(Y_n),
  .f = grf_fcn)

However, when I attempt to call the function it returns the error "Error in validate_observations(Y, X) : Observations (W, Y, Z or D) must be vectors." I find this curious as Y* and W are vectors. E.g.

> is.vector(df$Y1)
[1] TRUE
> is.vector(df$W)
[1] TRUE

Can anyone see where i'm going wrong here? Or is this a bug of some kind?

CodePudding user response:

To better understand where's the problem in your function, compare the output of the two following calls to map.

This one is the one you are using, it will return NULL:

purrr::map(tidyselect::all_of(Y_n), function(x) { df$x })

This one uses bracket notation, it will return the expected values:

purrr::map(tidyselect::all_of(Y_n), function(x) { df[[x]] })

This is a quirk of map and honestly I'm not quite sure what's going on under the hood, but at least we know how to modify your function to get your desired results:

grf_fcn <- function(x){
  Y <- df[[x]]
  W <- df$W
  
  c_forest <- causal_forest(
    X = X,
    W = W,
    Y = Y)
  
  ate_c_forest <- average_treatment_effect(
    c_forest, 
    target.sample = "overlap")
}
  • Related