Add horizontal line to terminal barplots in party / partykit trees

一世执手 提交于 2019-12-08 04:53:13

问题


I am using the ctree function from partykit.

library(rpart)
library(partykit)

fit <- ctree(Kyphosis ~ Age + Number + Start, data=kyphosis)
plot(fit, terminal_panel=node_barplot)

I want to add an additional horizonal line to each barplot, indicating the average reponse across the dataset, i.e. at 0.79 here.

prop.table(table(kyphosis$Kyphosis))

    absent   present 
 0.7901235 0.2098765

Approach: I started to modify the node_barplot function that is passed to the terminal_panel argument. But the source code is very long and comes with almost no comments. So I tried to go step by step, stripping down the function to its first two lines of code (plus an extra print command). However, if I run it, the object y is NULL and an error is thrown.

node_barplot2 <- function(obj, ...)
{   
  y <- obj$fitted[["(response)"]]   # first lime from node_barplot source
  print(y)
  stopifnot(is.factor(y) || isTRUE(all.equal(round(y), y)) || is.data.frame(y))
}

plot(fit, terminal_panel=node_barplot2)

> Error in round(y) : Non-numeric argument in mathematical function

As its the original code, I do not quite see where I go wrong here and how I could draw the horizontal line. Any ideas?


回答1:


The partykit distinguishes "panel" functions and "panel-generating" functions:

  • The former just expect the node of a tree as their sole argument and then draw this node (using grid graphics).

  • The latter expect a full tree as their first argument plus further arguments for customization. They return a "panel" function (with only argument node) where certain informations like the x and y ranges are stored in the function environment.

To signal that a function is a panel-generating function, it has to have class "grapcon_generator". Hence

class(node_barplot)
## [1] "grapcon_generator"

To add certain graphical elements to the function, I would recommend copying the whole node_barplot source code (including the class assignment at the end) and then add the elements you need, e.g., a horizontal reference line you can draw with grid.lines().




回答2:


Just for completeness: As Achim explained, the class attribute was not correct to indicate that the function has to be passed the whole tree, not just a node. Setting it to class(node_barplot2) <- "grapcon_generator" does the trick.

I slightly tweaked the node_barplot code and added two new arguments to the function: hline and h.gp. The first one specifies where the horizontal line is drawn (a value between 0 and 1). The line is the same across all terminal panels. The second one takes a gpar object used to style the drawn line. The function is named node_barplot2, you can find the gist here. The code that draws the line is at the end.

Example

library(devtools)
source_gist("0313362f0c84b21625bd")

plot(fit, terminal_panel = node_barplot2, 
     tp_args= list(hline = .8, 
                   h.gp = gpar(lwd=4, col="blue")))



来源:https://stackoverflow.com/questions/33784109/add-horizontal-line-to-terminal-barplots-in-party-partykit-trees

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!