Unable to pass NULL to boost_tree model

Can somebody explain why I can't pass a NULL variable into a boost_tree()?

library(tidyverse)
library(tidymodels)
library(xgboost)

set.seed(123)
#Load data
df <- as_tibble(iris)
# Split data
split <- initial_split(df, strata = Species)
train <- training(split)
test <- testing(split)
folds <- vfold_cv(train)

depth <- NULL # Defining an integer works fine
is.null(depth)

#Model
xg_model <-
  boost_tree(
    trees = 1000, 
    tree_depth = depth # Directly passing in NULL works fine
  ) %>%
  set_engine("xgboost") %>%
  set_mode("classification")

#Recipe
xg_recipe <-
  recipe(Species ~., data=split)

#Workflow
xg_workflow <-
  workflow() %>%
  add_recipe(xg_recipe) %>%
  add_model(xg_model)

#Fit
xg_fit <- 
  xg_workflow %>%
  last_fit(split) 

xg_fit_rs <- 
  xg_workflow %>% 
  fit_resamples(folds)
accuracy_xg <- xg_fit_rs %>% collect_metrics()
accuracy_xg

[1] TRUE
x train/test split: preprocessor 1/1, model 1/1: Error in xgb.iter.update(bst$handle, dtrain, iteration - 1, obj): Invalid Parameter format for max_de...

I think there is delayed evaluation of the inputs.
The default for tree_depth for boosted trees is 6L, when you use explicit NULL, tidymodels substitutes 6 and so can compute last_fit.
When you provide NULL in a depth variable, this had a delayed evaluation, and therefore seems to avoid being substituted for 6 is my guess. You can try the injection operator from rlang.

myfunc <- function(x){
  a <- rlang::enquo(x)
  cat("thanks for that will consider ",rlang::as_label(a))
}

myfunc(NULL)

foo <- NULL
myfunc(foo)
myfunc(!!foo)

i.e.

xg_model <-
  boost_tree(
    trees = 1000, 
    tree_depth = !!depth # Directly passing in NULL works fine
  ) %>%
  set_engine("xgboost") %>%
  set_mode("classification")
1 Like

Works perfectly! Thanks.

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

If you have a query related to it or one of the replies, start a new topic and refer back with a link.