Ottenere il percorso completo dalla foglia alla radice per ogni nodo terminale con ctree da partykit

Aug 21 2020

Attualmente sto lavorando con ctree dal pacchetto R "partykit" e mi chiedevo se esiste un modo per ottenere il percorso completo dai nodi terminali alla radice. Vorrei avere per ogni foglia il percorso completo della radice espresso come vettori contenenti gli ID dei nodi.

library(partykit)
ct <- ctree(Species ~ ., data = iris) 
Model formula:
Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width

Fitted party:
[1] root
|   [2] Petal.Length <= 1.9: setosa (n = 50, err = 0.0%)
|   [3] Petal.Length > 1.9
|   |   [4] Petal.Width <= 1.7
|   |   |   [5] Petal.Length <= 4.8: versicolor (n = 46, err = 2.2%)
|   |   |   [6] Petal.Length > 4.8: versicolor (n = 8, err = 50.0%)
|   |   [7] Petal.Width > 1.7: virginica (n = 46, err = 2.2%)

Number of inner nodes:    3
Number of terminal nodes: 4

Tracciare l'albero

Questo è fondamentalmente ciò di cui ho bisogno:

[[1]]
[1] 2 1

[[2]]
[1] 5 4 3 1

[[3]]
[1] 6 4 3 1

[[4]]
[1] 7 3 1

Gradirei qualsiasi aiuto! Grazie!

Risposte

AchimZeileis Aug 23 2020 at 06:48

La seguente funzione dovrebbe fare il trucco. La prima riga estrae un elenco di bambini per nodo e da questo puoi passare ricorsivamente attraverso tutti i nodi.

get_path <- function(object) {
  ## list of kids per node (NULL if terminal)
  kids <- lapply(as.list(object$node), "[[", "kids")

  ## recursively add node IDs of children
  add_ids <- function(x) {
    ki <- kids[[x[1L]]]
    if(is.null(ki)) {
      return(list(x))
    } else {
      x <- lapply(ki, "c", x)
      return(do.call("c", lapply(x, add_ids)))
    }
  }
  add_ids(1L)
}

Questo può quindi essere applicato a qualsiasi partyoggetto:

get_path(ct)
## [[1]]
## [1] 2 1
## 
## [[2]]
## [1] 5 4 3 1
## 
## [[3]]
## [1] 6 4 3 1
## 
## [[4]]
## [1] 7 3 1