Skip to content

Commit 6f26618

Browse files
authored
Merge pull request ndphillips#235 from hneth/master
Minor revisions
2 parents 2a1fdfd + 6f53832 commit 6f26618

10 files changed

Lines changed: 112 additions & 74 deletions

DESCRIPTION

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Package: FFTrees
22
Type: Package
33
Title: Generate, Visualise, and Evaluate Fast-and-Frugal Decision Trees
4-
Version: 2.1.0
5-
Date: 2025-09-03
4+
Version: 2.1.0.9001
5+
Date: 2026-05-02
66
Authors@R: c(person("Nathaniel", "Phillips", role = c("aut"), email = "Nathaniel.D.Phillips.is@gmail.com", comment = c(ORCID = "0000-0002-8969-7013")),
77
person("Hansjoerg", "Neth", role = c("aut", "cre"), email = "h.neth@uni.kn", comment = c(ORCID = "0000-0001-5427-3141")),
88
person("Jan", "Woike", role = "aut", comment = c(ORCID = "0000-0002-6816-121X")),
@@ -32,5 +32,5 @@ License: CC0
3232
URL: https://CRAN.R-project.org/package=FFTrees, https://www.nathanieldphillips.co/FFTrees/
3333
BugReports: https://github.com/ndphillips/FFTrees/issues
3434
VignetteBuilder: knitr
35-
RoxygenNote: 7.3.2
35+
RoxygenNote: 7.3.3
3636
Language: en-US

R/fftrees_cuerank.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535

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

4141
# Prepare: ------
4242

README.Rmd

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,16 @@ doi_JDM <- "10.1017/S1930297500006239"
3737
# FFTrees `r packageVersion("FFTrees")` <img src = "man/figures/logo.png" align = "right" alt = "FFTrees" width = "160" />
3838

3939
<!-- Devel badges start: -->
40-
<!-- [![CRAN status](https://www.r-pkg.org/badges/version/FFTrees)](https://CRAN.R-project.org/package=FFTrees) -->
41-
<!-- [![Downloads/month](https://cranlogs.r-pkg.org/badges/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees) -->
42-
<!-- [![Total downloads](https://cranlogs.r-pkg.org/badges/grand-total/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees) -->
43-
<!-- [![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) -->
40+
[![CRAN status](https://www.r-pkg.org/badges/version/FFTrees)](https://CRAN.R-project.org/package=FFTrees)
41+
[![Downloads/month](https://cranlogs.r-pkg.org/badges/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees)
42+
[![Total downloads](https://cranlogs.r-pkg.org/badges/grand-total/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees)
43+
[![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)
4444
<!-- Devel badges end. -->
4545

4646

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

5252

@@ -106,8 +106,39 @@ library(FFTrees) # load package
106106
```
107107

108108

109+
### Questions answered by FFTs
110+
111+
<!-- 0. FFTs provide binary predictions: -->
112+
113+
A _fast-and-frugal tree_ (FFT) provides answers to binary prediction problems like:
114+
115+
- Which of 2 categories should we predict for each individual case in the data?
116+
- How successful is this prediction process for a sample of cases?
117+
118+
<!-- 1. Creating FFTs: -->
119+
120+
To _create_ FFTs, we must answer 2 key questions:
121+
122+
- Which variables should we use to predict the criterion?
123+
- How should we combine those predictor variables into FFTs?
124+
125+
<!-- 2. Measuring performance of FFTs: -->
126+
127+
Once we have created FFTs, questions regarding their _performance_ include:
128+
129+
- How accurate are the predictions of a specific FFT?
130+
- How costly are the predictions of each algorithm?
131+
132+
Answering these performance-related questions requires applying FFTs to data.
133+
134+
<!-- The FFTrees package: -->
135+
136+
The **FFTrees** package answers these questions by creating, evaluating, and visualizing FFTs.
137+
138+
109139
### Using data
110140

141+
Any prediction problem requires some data that contains some predictors and a criterion variable.
111142
The `heartdisease` data provides medical information for 303\ patients that were examined for heart disease.
112143
The full data contains a binary criterion variable describing the true state of each patient and were split into two subsets:
113144
A `heart.train` set for fitting decision trees, and `heart.test` set for a testing these trees.
@@ -134,21 +165,6 @@ knitr::kable(head(heart.test), caption = c_test)
134165
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.
135166

136167

137-
### Questions answered by FFTs
138-
139-
To solve binary classification problems by FFTs, we must answer two key questions:
140-
141-
- Which of the variables should we use to predict the criterion?
142-
- How should we use and combine predictor variables into FFTs?
143-
144-
Once we have created some FFTs, additional questions include:
145-
146-
- How accurate are the predictions of a specific FFT?
147-
- How costly are the predictions of each algorithm?
148-
149-
The **FFTrees** package answers these questions by creating, evaluating, and visualizing FFTs.
150-
151-
152168
### Creating fast-and-frugal trees (FFTs)
153169

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

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

284-
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).
300+
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).
285301
Examples include:
286302

287303
- 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.
@@ -308,6 +324,7 @@ Age at diagnosis, but not HPV type, is strongly associated with clinical course
308324
_PloS One_, _14_(6).
309325
doi\ [10.1371/journal.pone.0216697](https://doi.org/10.1371/journal.pone.0216697)
310326

327+
311328
<!-- footer: -->
312329

313330
----

README.md

Lines changed: 57 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,24 @@
33

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

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

88
<!-- Devel badges start: -->
99

10-
<!-- [![CRAN status](https://www.r-pkg.org/badges/version/FFTrees)](https://CRAN.R-project.org/package=FFTrees) -->
11-
12-
<!-- [![Downloads/month](https://cranlogs.r-pkg.org/badges/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees) -->
13-
14-
<!-- [![Total downloads](https://cranlogs.r-pkg.org/badges/grand-total/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees) -->
15-
16-
<!-- [![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) -->
17-
18-
<!-- Devel badges end. -->
19-
20-
<!-- Release badges start: -->
21-
2210
[![CRAN
2311
status](https://www.r-pkg.org/badges/version/FFTrees)](https://CRAN.R-project.org/package=FFTrees)
12+
[![Downloads/month](https://cranlogs.r-pkg.org/badges/FFTrees?color=%2200a9e0%22)](https://www.r-pkg.org/pkg/FFTrees)
2413
[![Total
2514
downloads](https://cranlogs.r-pkg.org/badges/grand-total/FFTrees?color=%2200a9e0%22)](https://www.r-pkg.org/pkg/FFTrees)
15+
[![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)
16+
<!-- Devel badges end. -->
17+
18+
<!-- Release badges start: -->
19+
20+
<!-- [![CRAN status](https://www.r-pkg.org/badges/version/FFTrees)](https://CRAN.R-project.org/package=FFTrees) -->
21+
22+
<!-- [![Total downloads](https://cranlogs.r-pkg.org/badges/grand-total/FFTrees?color="00a9e0")](https://www.r-pkg.org/pkg/FFTrees) -->
23+
2624
<!-- Release badges end. -->
2725

2826
<!-- ALL badges start: -->
@@ -102,14 +100,50 @@ included in **FFTrees**:
102100
library(FFTrees) # load package
103101
```
104102

103+
### Questions answered by FFTs
104+
105+
<!-- 0. FFTs provide binary predictions: -->
106+
107+
A *fast-and-frugal tree* (FFT) provides answers to binary prediction
108+
problems like:
109+
110+
- Which of 2 categories should we predict for each individual case in
111+
the data?
112+
- How successful is this prediction process for a sample of cases?
113+
114+
<!-- 1. Creating FFTs: -->
115+
116+
To *create* FFTs, we must answer 2 key questions:
117+
118+
- Which variables should we use to predict the criterion?
119+
- How should we combine those predictor variables into FFTs?
120+
121+
<!-- 2. Measuring performance of FFTs: -->
122+
123+
Once we have created FFTs, questions regarding their *performance*
124+
include:
125+
126+
- How accurate are the predictions of a specific FFT?
127+
- How costly are the predictions of each algorithm?
128+
129+
Answering these performance-related questions requires applying FFTs to
130+
data.
131+
132+
<!-- The FFTrees package: -->
133+
134+
The **FFTrees** package answers these questions by creating, evaluating,
135+
and visualizing FFTs.
136+
105137
### Using data
106138

107-
The `heartdisease` data provides medical information for 303 patients
108-
that were examined for heart disease. The full data contains a binary
109-
criterion variable describing the true state of each patient and were
110-
split into two subsets: A `heart.train` set for fitting decision trees,
111-
and `heart.test` set for a testing these trees. Here are the first rows
112-
and columns of both subsets of the `heartdisease` data:
139+
Any prediction problem requires some data that contains some predictors
140+
and a criterion variable. The `heartdisease` data provides medical
141+
information for 303 patients that were examined for heart disease. The
142+
full data contains a binary criterion variable describing the true state
143+
of each patient and were split into two subsets: A `heart.train` set for
144+
fitting decision trees, and `heart.test` set for a testing these trees.
145+
Here are the first rows and columns of both subsets of the
146+
`heartdisease` data:
113147

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

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

148-
### Questions answered by FFTs
149-
150-
To solve binary classification problems by FFTs, we must answer two key
151-
questions:
152-
153-
- Which of the variables should we use to predict the criterion?
154-
- How should we use and combine predictor variables into FFTs?
155-
156-
Once we have created some FFTs, additional questions include:
157-
158-
- How accurate are the predictions of a specific FFT?
159-
- How costly are the predictions of each algorithm?
160-
161-
The **FFTrees** package answers these questions by creating, evaluating,
162-
and visualizing FFTs.
163-
164182
### Creating fast-and-frugal trees (FFTs)
165183

166184
We use the main `FFTrees()` function to create FFTs for the
@@ -195,7 +213,7 @@ plot(heart_fft,
195213
main = "Heart Disease")
196214
```
197215

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

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

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

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

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

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

345363
------------------------------------------------------------------------
346364

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

349367
<!-- eof. -->

inst/HeartFFT.jpeg

-72.8 KB
Binary file not shown.
-12 Bytes
Loading
30 Bytes
Loading

vignettes/FFTrees_examples.Rmd

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,20 +164,20 @@ knitr::include_graphics("virginica.jpg")
164164
```
165165

166166
The `iris.v` dataset contains data about 150\ flowers (see `?iris.v`).
167-
Our goal is to predict which flowers are of the class _Virginica_.
168-
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:
167+
Our present goal is to predict which flowers are of the class _Virginica_.
168+
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:
169169

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

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

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

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

204204

vignettes/FFTrees_mytree.Rmd

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ summary(y)
589589
# plot(y, tree = 1)
590590
```
591591

592-
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.
592+
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.
593593
Upon reflection, this is not surprising: Most people are still classified into the same categories as before.
594594
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.
595595

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

599599
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.
600600
This circumvented the FFT building algorithms and used the provided FFT definitions instead.
601-
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.
601+
Thus, the ordinary distinction between training and test data no longer applies in this context:
602+
As no model is being fitted here, both sets were used to evaluate (or "test") the FFTs in `tree.definitions` on these data.
602603
<!-- 1. Using only data, as train vs. data.test not used here: -->
603604
Acknowledging this, we may use the full dataset of `heartdisease`, rather than splitting it into two distinct subsets:
604605

vignettes/FFTrees_plot.Rmd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ knitr::opts_chunk$set(collapse = FALSE,
3131
library(FFTrees)
3232
```
3333

34+
3435
## Visualizing FFTrees
3536

3637
The **FFTrees** package makes it very easy to visualize and evaluate fast-and-frugal trees (FFTs):
@@ -122,6 +123,7 @@ By contrast, `age`\ (3) seems a pretty poor cue for predicting survival on its o
122123
Inspecting cue accuracies can provide valuable information for constructing FFTs.
123124
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.
124125
126+
125127
### Visualizing FFTs and their performance
126128
127129
To visualize the tree from an `FFTrees` object, use `plot()`.

0 commit comments

Comments
 (0)