---
title: "randomForest() model"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{randomForest}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
menu:
  main:
    parent: "articles"
    weight: 3
---

```{r setup, include=FALSE}
library(dplyr)
library(tidypredict)
library(randomForest)
set.seed(100)
```

## Highlights & Limitations

- Uses the `randomForest::getTree()` to parse each decision path.
- In-line functions in the formulas are **not supported**:  
     - OK - `wt ~ mpg + am` 
     - OK - `mutate(mtcars, newam = paste0(am))` and then `wt ~ mpg + newam`
     - Not OK - `wt ~ mpg + as.factor(am)`
     - Not OK - `wt ~ mpg + as.character(am)`
- Interval functions are not supported: `tidypredict_interval()` & `tidypredict_sql_interval()`
   

## How it works

Here is a simple `randomForest()` model using the `iris` dataset:
```{r}
library(randomForest)
model <- randomForest(Species ~ .,data = iris ,ntree = 100, proximity = TRUE)
```

The SQL translations returns a single SQL `CASE WHEN` operation.  Each decision path is a `WHEN` statement.
```{r}
library(tidypredict)

tidypredict_sql(model, dbplyr::simulate_mssql())
```

Alternatively, use `tidypredict_to_column()` if the results are the be used or previewed in `dplyr`.

```{r}
iris %>%
  tidypredict_to_column(model) %>%
  head(10)
```

## Under the hood

The parser is based on the output from the `randomForest::getTree()` function.  It will return as many decision paths as there are non-NA rows in the `prediction` field.
```{r}
getTree(model, labelVar = TRUE) %>%
  head()
```

The parsed model contains one row for each path.  The `field`, `operator` and `split_point` field list every step in a concatenated character variable.
```{r}
parse_model(model)
```

The output from `parse_model()` is transformed into a `dplyr`, a.k.a Tidy Eval, formula.  The entire decision tree becomes one `dplyr::case_when()` statement
```{r}
tidypredict_fit(model)
```

From there, the Tidy Eval formula can be used anywhere where it can be operated. `tidypredict` provides three paths:

  - Use directly inside `dplyr`,  `mutate(iris, !! tidypredict_fit(model))`
  - Use `tidypredict_to_column(model)` to a piped command set
  - Use `tidypredict_to_sql(model)` to retrieve the SQL statement

## How it performs

Currently, the formula matches 147 out of 150 prediction of the test model. The `threshold` in `tidypredict_test()` is a integer indicating the number of records are OK to be different than the baseline prediction that the `predict()` function returns. 
```{r}
test <- tidypredict_test(model, iris, threshold = 5)

test

test$raw_results %>%
  filter(predict != tidypredict)
```