将水平线添加到派对/派对包树中的终端条形图

Add horizontal line to terminal barplots in party / partykit trees

我正在使用 partykit 中的 ctree 函数。

library(rpart)
library(partykit)

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

我想为每个条形图添加一条额外的水平线,指示整个数据集的平均响应,即此处为 0.79。

prop.table(table(kyphosis$Kyphosis))

    absent   present 
 0.7901235 0.2098765

方法:我开始修改传递给terminal_panel参数的node_barplot函数。但是源代码很长,几乎没有注释。所以我试着一步一步来,将函数剥离到它的前两行代码(加上一个额外的打印命令)。但是,如果我 运行 它,对象 yNULL 并且抛出错误。

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

作为原始代码,我不太明白哪里出错了如何绘制水平线。有什么想法吗?

partykit区分"panel"函数和"panel-generating"函数:

  • 前者只是期望树的node作为他们唯一的参数,然后绘制这个节点(使用grid图形)。

  • 后者期望一棵完整的树作为他们的第一个参数加上进一步的自定义参数。它们 return 一个 "panel" 函数(只有参数 node),其中 x 和 y 范围等某些信息存储在函数环境中。

要表明函数是面板生成函数,它必须具有 class "grapcon_generator"。因此

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

要向函数添加某些图形元素,我建议复制整个 node_barplot 源代码(包括末尾的 class 赋值),然后添加您需要的元素,例如,您可以使用 grid.lines().

绘制的水平参考线

只是为了完整性:正如 Achim 所解释的,class 属性不正确,表明函数必须传递整棵树,而不仅仅是一个节点。将其设置为 class(node_barplot2) <- "grapcon_generator" 就可以了。

我稍微调整了 node_barplot 代码并向函数添加了两个新参数:hlineh.gp。第一个指定绘制水平线的位置(一个介于 0 和 1 之间的值)。该线在所有终端面板上都相同。第二个采用 gpar 对象,用于设置绘制线条的样式。该函数名为node_barplot2,您可以找到要点here。画线的代码在最后。

例子

library(devtools)
source_gist("0313362f0c84b21625bd")

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