Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Package: FFTrees
Type: Package
Title: Generate, Visualise, and Evaluate Fast-and-Frugal Decision Trees
Version: 2.1.0
Date: 2025-09-03
Version: 2.1.0.9001
Date: 2026-05-02
Authors@R: c(person("Nathaniel", "Phillips", role = c("aut"), email = "Nathaniel.D.Phillips.is@gmail.com", comment = c(ORCID = "0000-0002-8969-7013")),
person("Hansjoerg", "Neth", role = c("aut", "cre"), email = "h.neth@uni.kn", comment = c(ORCID = "0000-0001-5427-3141")),
person("Jan", "Woike", role = "aut", comment = c(ORCID = "0000-0002-6816-121X")),
Expand Down Expand Up @@ -32,5 +32,5 @@ License: CC0
URL: https://CRAN.R-project.org/package=FFTrees, https://www.nathanieldphillips.co/FFTrees/
BugReports: https://github.com/ndphillips/FFTrees/issues
VignetteBuilder: knitr
RoxygenNote: 7.3.2
RoxygenNote: 7.3.3
Language: en-US
4 changes: 2 additions & 2 deletions R/fftrees_cuerank.R
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@

fftrees_cuerank <- function(x = NULL,
newdata = NULL,
data = "train", # type of data
rounding = NULL) {
data = "train", # type of data
rounding = NULL) { # ToDo: Use a sensible default, e.g., rounding = 3 (in the FFTrees() function)

# Prepare: ------

Expand Down
61 changes: 39 additions & 22 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ doi_JDM <- "10.1017/S1930297500006239"
# FFTrees `r packageVersion("FFTrees")` <img src = "man/figures/logo.png" align = "right" alt = "FFTrees" width = "160" />

<!-- Devel badges start: -->
<!-- [![CRAN status](https://www.r-pkg.org/badges/version/FFTrees)](https://CRAN.R-project.org/package=FFTrees) -->
<!-- [![Downloads/month](https://cranlogs.r-pkg.org/badges/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees) -->
<!-- [![Total downloads](https://cranlogs.r-pkg.org/badges/grand-total/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees) -->
<!-- [![R-CMD-check](https://github.com/ndphillips/FFTrees/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/ndphillips/FFTrees/actions/workflows/R-CMD-check.yaml) -->
[![CRAN status](https://www.r-pkg.org/badges/version/FFTrees)](https://CRAN.R-project.org/package=FFTrees)
[![Downloads/month](https://cranlogs.r-pkg.org/badges/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees)
[![Total downloads](https://cranlogs.r-pkg.org/badges/grand-total/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees)
[![R-CMD-check](https://github.com/ndphillips/FFTrees/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/ndphillips/FFTrees/actions/workflows/R-CMD-check.yaml)
<!-- Devel badges end. -->


<!-- Release badges start: -->
[![CRAN status](https://www.r-pkg.org/badges/version/FFTrees)](https://CRAN.R-project.org/package=FFTrees)
[![Total downloads](https://cranlogs.r-pkg.org/badges/grand-total/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees)
<!-- [![CRAN status](https://www.r-pkg.org/badges/version/FFTrees)](https://CRAN.R-project.org/package=FFTrees) -->
<!-- [![Total downloads](https://cranlogs.r-pkg.org/badges/grand-total/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees) -->
<!-- Release badges end. -->


Expand Down Expand Up @@ -106,8 +106,39 @@ library(FFTrees) # load package
```


### Questions answered by FFTs

<!-- 0. FFTs provide binary predictions: -->

A _fast-and-frugal tree_ (FFT) provides answers to binary prediction problems like:

- Which of 2 categories should we predict for each individual case in the data?
- How successful is this prediction process for a sample of cases?

<!-- 1. Creating FFTs: -->

To _create_ FFTs, we must answer 2 key questions:

- Which variables should we use to predict the criterion?
- How should we combine those predictor variables into FFTs?

<!-- 2. Measuring performance of FFTs: -->

Once we have created FFTs, questions regarding their _performance_ include:

- How accurate are the predictions of a specific FFT?
- How costly are the predictions of each algorithm?

Answering these performance-related questions requires applying FFTs to data.

<!-- The FFTrees package: -->

The **FFTrees** package answers these questions by creating, evaluating, and visualizing FFTs.


### Using data

Any prediction problem requires some data that contains some predictors and a criterion variable.
The `heartdisease` data provides medical information for 303\ patients that were examined for heart disease.
The full data contains a binary criterion variable describing the true state of each patient and were split into two subsets:
A `heart.train` set for fitting decision trees, and `heart.test` set for a testing these trees.
Expand All @@ -134,21 +165,6 @@ knitr::kable(head(heart.test), caption = c_test)
Our challenge is to predict each patient's `diagnosis` ---\ a column of logical values indicating the true state of each patient (i.e., `TRUE` or\ `FALSE`, based on the patient suffering or not suffering from heart disease)\ --- from the values of potential predictors.


### Questions answered by FFTs

To solve binary classification problems by FFTs, we must answer two key questions:

- Which of the variables should we use to predict the criterion?
- How should we use and combine predictor variables into FFTs?

Once we have created some FFTs, additional questions include:

- How accurate are the predictions of a specific FFT?
- How costly are the predictions of each algorithm?

The **FFTrees** package answers these questions by creating, evaluating, and visualizing FFTs.


### Creating fast-and-frugal trees (FFTs)

We use the main `FFTrees()` function to create FFTs for the `heart.train` data and evaluate their predictive performance on the `heart.test` data:
Expand Down Expand Up @@ -281,7 +297,7 @@ When using **FFTrees** in your own work, please cite us and share your experienc

<!-- Examples uses/publications (with links): -->

By\ 2025, over 150\ scientific publications have used or cited **FFTrees** (see [Google Scholar](https://scholar.google.com/scholar?oi=bibs&hl=en&cites=205528310591558601) for the full list).
By\ 2026, over 160\ scientific publications have used or cited **FFTrees** (see [Google Scholar](https://scholar.google.com/scholar?oi=bibs&hl=en&cites=205528310591558601) for the full list).
Examples include:

- Lötsch, J., Haehner, A., & Hummel, T. (2020). Machine-learning-derived rules set excludes risk of Parkinson’s disease in patients with olfactory or gustatory symptoms with high accuracy.
Expand All @@ -308,6 +324,7 @@ Age at diagnosis, but not HPV type, is strongly associated with clinical course
_PloS One_, _14_(6).
doi\ [10.1371/journal.pone.0216697](https://doi.org/10.1371/journal.pone.0216697)


<!-- footer: -->

----
Expand Down
96 changes: 57 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,24 @@

<!-- Title, version and logo: -->

# FFTrees 2.1.0 <img src = "man/figures/logo.png" align = "right" alt = "FFTrees" width = "160" />
# FFTrees 2.1.0.9001 <img src = "man/figures/logo.png" align = "right" alt = "FFTrees" width = "160" />

<!-- Devel badges start: -->

<!-- [![CRAN status](https://www.r-pkg.org/badges/version/FFTrees)](https://CRAN.R-project.org/package=FFTrees) -->

<!-- [![Downloads/month](https://cranlogs.r-pkg.org/badges/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees) -->

<!-- [![Total downloads](https://cranlogs.r-pkg.org/badges/grand-total/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees) -->

<!-- [![R-CMD-check](https://github.com/ndphillips/FFTrees/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/ndphillips/FFTrees/actions/workflows/R-CMD-check.yaml) -->

<!-- Devel badges end. -->

<!-- Release badges start: -->

[![CRAN
status](https://www.r-pkg.org/badges/version/FFTrees)](https://CRAN.R-project.org/package=FFTrees)
[![Downloads/month](https://cranlogs.r-pkg.org/badges/FFTrees?color=%2200a9e0%22)](https://www.r-pkg.org/pkg/FFTrees)
[![Total
downloads](https://cranlogs.r-pkg.org/badges/grand-total/FFTrees?color=%2200a9e0%22)](https://www.r-pkg.org/pkg/FFTrees)
[![R-CMD-check](https://github.com/ndphillips/FFTrees/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/ndphillips/FFTrees/actions/workflows/R-CMD-check.yaml)
<!-- Devel badges end. -->

<!-- Release badges start: -->

<!-- [![CRAN status](https://www.r-pkg.org/badges/version/FFTrees)](https://CRAN.R-project.org/package=FFTrees) -->

<!-- [![Total downloads](https://cranlogs.r-pkg.org/badges/grand-total/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees) -->

<!-- Release badges end. -->

<!-- ALL badges start: -->
Expand Down Expand Up @@ -102,14 +100,50 @@ included in **FFTrees**:
library(FFTrees) # load package
```

### Questions answered by FFTs

<!-- 0. FFTs provide binary predictions: -->

A *fast-and-frugal tree* (FFT) provides answers to binary prediction
problems like:

- Which of 2 categories should we predict for each individual case in
the data?
- How successful is this prediction process for a sample of cases?

<!-- 1. Creating FFTs: -->

To *create* FFTs, we must answer 2 key questions:

- Which variables should we use to predict the criterion?
- How should we combine those predictor variables into FFTs?

<!-- 2. Measuring performance of FFTs: -->

Once we have created FFTs, questions regarding their *performance*
include:

- How accurate are the predictions of a specific FFT?
- How costly are the predictions of each algorithm?

Answering these performance-related questions requires applying FFTs to
data.

<!-- The FFTrees package: -->

The **FFTrees** package answers these questions by creating, evaluating,
and visualizing FFTs.

### Using data

The `heartdisease` data provides medical information for 303 patients
that were examined for heart disease. The full data contains a binary
criterion variable describing the true state of each patient and were
split into two subsets: A `heart.train` set for fitting decision trees,
and `heart.test` set for a testing these trees. Here are the first rows
and columns of both subsets of the `heartdisease` data:
Any prediction problem requires some data that contains some predictors
and a criterion variable. The `heartdisease` data provides medical
information for 303 patients that were examined for heart disease. The
full data contains a binary criterion variable describing the true state
of each patient and were split into two subsets: A `heart.train` set for
fitting decision trees, and `heart.test` set for a testing these trees.
Here are the first rows and columns of both subsets of the
`heartdisease` data:

- `heart.train` (the training / fitting data) describes 150 patients:

Expand Down Expand Up @@ -145,22 +179,6 @@ logical values indicating the true state of each patient (i.e., `TRUE`
or `FALSE`, based on the patient suffering or not suffering from heart
disease) — from the values of potential predictors.

### Questions answered by FFTs

To solve binary classification problems by FFTs, we must answer two key
questions:

- Which of the variables should we use to predict the criterion?
- How should we use and combine predictor variables into FFTs?

Once we have created some FFTs, additional questions include:

- How accurate are the predictions of a specific FFT?
- How costly are the predictions of each algorithm?

The **FFTrees** package answers these questions by creating, evaluating,
and visualizing FFTs.

### Creating fast-and-frugal trees (FFTs)

We use the main `FFTrees()` function to create FFTs for the
Expand Down Expand Up @@ -195,7 +213,7 @@ plot(heart_fft,
main = "Heart Disease")
```

<img src="man/figures/README-example-heart-plot-1.png" width="650" style="display: block; margin: auto;" />
<img src="man/figures/README-example-heart-plot-1.png" alt="" width="650" style="display: block; margin: auto;" />

**Figure 1**: A fast-and-frugal tree (FFT) predicting heart disease for
`test` data and its performance characteristics.
Expand Down Expand Up @@ -239,7 +257,7 @@ plot(my_fft,
main = "My custom FFT")
```

<img src="man/figures/README-example-heart-verbal-1.png" width="650" style="display: block; margin: auto;" />
<img src="man/figures/README-example-heart-verbal-1.png" alt="" width="650" style="display: block; margin: auto;" />

**Figure 2**: An FFT predicting heart disease created from a verbal
description.
Expand Down Expand Up @@ -304,7 +322,7 @@ continue developing the package.

<!-- Examples uses/publications (with links): -->

By 2025, over 150 scientific publications have used or cited **FFTrees**
By 2026, over 160 scientific publications have used or cited **FFTrees**
(see [Google
Scholar](https://scholar.google.com/scholar?oi=bibs&hl=en&cites=205528310591558601)
for the full list). Examples include:
Expand Down Expand Up @@ -344,6 +362,6 @@ for the full list). Examples include:

------------------------------------------------------------------------

\[File `README.Rmd` last updated on 2025-09-03.\]
\[File `README.Rmd` last updated on 2026-05-02.\]

<!-- eof. -->
Binary file removed inst/HeartFFT.jpeg
Binary file not shown.
Binary file modified man/figures/README-example-heart-plot-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified man/figures/README-example-heart-verbal-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 6 additions & 6 deletions vignettes/FFTrees_examples.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -164,20 +164,20 @@ knitr::include_graphics("virginica.jpg")
```

The `iris.v` dataset contains data about 150\ flowers (see `?iris.v`).
Our goal is to predict which flowers are of the class _Virginica_.
In this example, we'll create trees using the entire dataset (without splitting the available data into explicit training vs. test subsets), so that we are really fitting the data, rather than engaging in genuine prediction:
Our present goal is to predict which flowers are of the class _Virginica_.
In this example, we create trees using the entire dataset (without splitting the available data into explicit training vs. test subsets), so that we are really fitting the data, rather than engaging in prediction:

```{r iris-fft, message = FALSE, results = 'hide'}
# Create FFTrees object for iris data:
iris_fft <- FFTrees(formula = virginica ~.,
data = iris.v,
main = "Iris viginica",
main = "Iris virginica",
decision.labels = c("Not-Vir", "Vir"))
```

The **FFTrees** package provides various functions to inspect the `FFTrees` object `iris_fft`.
The **FFTrees** package provides various functions to inspect the `FFTrees` object\ `iris_fft`.
For summary information on the best training tree, we can print the `FTrees` object (by evaluating `iris_fft` or `print(iris_fft)`).
Alternatively, we could visualize the tree (via `plot(iris_fft)`) or summarize the `FFTrees` object (via `summary(iris_fft)`):
Alternatively, we can visualize the tree (via `plot(iris_fft)`) or summarize the `FFTrees` object (via `summary(iris_fft)`):

```{r iris-fft-print, echo = TRUE, eval = FALSE, results = 'hide'}
# Inspect resulting FFTs:
Expand All @@ -198,7 +198,7 @@ We can plot the training cue accuracies during training by specifying `what = "c
plot(iris_fft, what = "cues")
```

It looks like the two cues\ `pet.len` and\ `pet.wid` are the best predictors for this dataset.
It looks like the two cues\ `pet.len` and\ `pet.wid` are the best predictors for this data.
Based on this insight, we should expect the final trees will likely use one or both of these cues.


Expand Down
5 changes: 3 additions & 2 deletions vignettes/FFTrees_mytree.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ summary(y)
# plot(y, tree = 1)
```

Comparing the accuracy statistics of our new FFTs (in object\ `y`) to our original FFTs (in object\ `x`) shows that swapping the 2nd and 3rd cue had hardly an effect.
Comparing the accuracy statistics of our new FFTs (in object\ `y`) to our original FFTs (in object\ `x`) shows that swapping the 2nd and 3rd cues hardly had an\ effect.
Upon reflection, this is not surprising: Most people are still classified into the same categories as before.
However, if we were to evaluate the costs of classification (e.g., by considering the\ `pci` and\ `mcu` measures or the `cost` measures for cue usage), we could still detect differences between FFTs that show the same accuracy.

Expand All @@ -598,7 +598,8 @@ However, if we were to evaluate the costs of classification (e.g., by considerin

We just created a new `FFTrees` object\ `y` by using `FFTrees` object\ `x` for a set of customized FFTs defined by the `tree.definitions` argument.
This circumvented the FFT building algorithms and used the provided FFT definitions instead.
Thus, the ordinary distinction between training and test data no longer applies in this context: As no model is being fitted here, both sets were used to evaluate the FFTs in `tree.definitions` on these data.
Thus, the ordinary distinction between training and test data no longer applies in this context:
As no model is being fitted here, both sets were used to evaluate (or "test") the FFTs in `tree.definitions` on these data.
<!-- 1. Using only data, as train vs. data.test not used here: -->
Acknowledging this, we may use the full dataset of `heartdisease`, rather than splitting it into two distinct subsets:

Expand Down
2 changes: 2 additions & 0 deletions vignettes/FFTrees_plot.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ knitr::opts_chunk$set(collapse = FALSE,
library(FFTrees)
```


## Visualizing FFTrees

The **FFTrees** package makes it very easy to visualize and evaluate fast-and-frugal trees (FFTs):
Expand Down Expand Up @@ -122,6 +123,7 @@ By contrast, `age`\ (3) seems a pretty poor cue for predicting survival on its o
Inspecting cue accuracies can provide valuable information for constructing FFTs.
While they provide lower bounds on the performance of trees (as combining cues is only worthwhile when this yields a benefit), even poor individual cues can shine in combination with other predictors.


### Visualizing FFTs and their performance

To visualize the tree from an `FFTrees` object, use `plot()`.
Expand Down
Loading