Consolidate party rules

Viewed 427

A simple example

>library(partykit)
> partykit:::.list.rules.party(ctree(Petal.Length~.,data=iris))
                                                                                                     2 
                                                                                  "Petal.Width <= 0.6" 
                                                                                                     6 
                  "Petal.Width > 0.6 & Sepal.Length <= 6.2 & Petal.Width <= 1.3 & Sepal.Length <= 5.5" 
                                                                                                     7 
                   "Petal.Width > 0.6 & Sepal.Length <= 6.2 & Petal.Width <= 1.3 & Sepal.Length > 5.5" 
                                                                                                     ....

For example, in the second rule, the two occurrences of Sepal.Length can be consolidated into Sepal.Length<=5.5

So, is there a way to consolidate the rules?

3 Answers

A simpler version:

"Petal.Width > 0.6 & Sepal.Length <= 6.2 & Petal.Width <= 1.3 & Sepal.Length <= 5.5" %>%
    str_split(' & ') %>% unlist() %>% str_split(' ') %>%
    lapply(function(x) data.frame(var = x[1], cond = x[2], value = tail(x, -2) %>% paste(collapse = ' '))) %>% bind_rows() %>%
    group_by(var, cond) %>%
    filter(
        if (str_detect(unique(cond), '<')) 1:n() == which.min(as.numeric(value))
        else if (str_detect(unique(cond), '>')) 1:n() == which.max(as.numeric(value))
        else 1:n() == which.min(str_count(value, ','))
    ) %>%
    apply(1, paste, collapse = ' ') %>% paste(collapse = ' & ')

[1] "Petal.Width > 0.6 & Petal.Width <= 1.3 & Sepal.Length <= 5.5"

It works by splitting the rule using & as marker and then split again each element (eg.: Petal.Width > 0.6) into its three components (eg, the variable Petal.Width, the condition > and the value 0.6). I make everything into a dataframe, group by variable and condition and then choose the right element according to the condition. Finally I collapse first by row and then again in one string.

I come up with it today, so I didn't test it thoroughly yet but should work. It requires the dplyr and stringr packages. Note that this code works on a single rule, but you can use it with vectors of strings with sapply().

Related