如何在rpart中获取父节点的名称?

时间:2018-10-30 05:51:41

标签: r plot cran party

嗨,我目前正在尝试提取存储在聚会对象中的某些父节点信息,例如ID。现在,我可以使用以下方法获取终端节点的ID:

 fit<-rpart(CommuteDistance ~.,data = Clients)
 pr<-as.party(fit)
 nodeids(pr,terminal=TRUE)

但是我如何获得家长ID?如果可能的话,如何获取节点名称?

2 个答案:

答案 0 :(得分:0)

没有便捷可用的功能可轻松提取。但是,不难简单地遍历递归partynode结构并获得您感兴趣的自定义数量。这还有助于先将递归partynode转换为平面列表。

作为可重现的示例,请考虑以下rpart树及其party表示形式:

library("rpart")
fit <- rpart(Petal.Length ~ ., data = iris)
library("partykit")
pr <- as.party(fit)

之后,您可以轻松地转换为as.list(pr$node),它从递归partynode结构中返回所有信息。特别是,它包含每个节点的$id$kids ID(如果有)。因此,我们可以使用sapply()和自定义函数轻松提取它们:

sapply(as.list(pr$node), function(n) {
  if(is.null(n$kids)) c(n$id, NA, NA) else c(n$id, n$kids)
})
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
## [1,]    1    2    3    4    5    6    7    8    9
## [2,]    2   NA    4    5   NA   NA    8   NA   NA
## [3,]    3   NA    7    6   NA   NA    9   NA   NA

在第一列中显示节点1有两个孩子,节点2和3。节点2是终端节点,因为它没有孩子(第二列),而节点3又有两个孩子,节点4和7,依此类推。

答案 1 :(得分:0)

由于节点 ID 遵循一个很好的模式,您可以简单地通过 parent_id = floor(node_id/2) 来确定父 ID。

这是一个最小的工作示例,用于获得一个表,其中包含节点 ID 与其父 ID 的映射。在其中,我使用 tidyverse 中的 rownames_to_column 函数来获取 node_ids 而不是使用 partykit,但方法是类似的:

library("rpart")
library("tidyverse")
fit <- rpart(Petal.Length ~ ., data = iris)


get_frame_with_parent <- function(x) {
  frame_with_parent <- 
    x$frame %>%
    tibble::rownames_to_column(var = "node_id") %>%
    mutate(node_id = as.numeric(node_id),
           parent_id = floor(node_id/2))
  frame_with_parent
}
frame_with_parent

可以使用labels(fit)来获取节点名称

对于一个最小的工作示例,将这两个东西结合起来得到一个包含节点 ID、节点标签、父 ID 和父标签的表:

library("rpart")
library("tidyverse")
fit <- rpart(Petal.Length ~ ., data = iris)

get_frame_with_parent <- function(x) {
  frame_with_parent <- 
    x$frame %>%
    mutate(node_label = labels(x)) %>%
    tibble::rownames_to_column(var = "node_id") %>%
    mutate(node_id = as.numeric(node_id),
           parent_id = floor(node_id/2))
  
  frame_with_parent <-
    frame_with_parent %>%
    left_join(
      dplyr::select(frame_with_parent, node_id, node_label),
      by = c("parent_id" = "node_id"),
      suffix = c("", ".y")
    ) %>%
    dplyr::rename(parent_label = node_label.y)
  
  frame_with_parent
}
get_frame_with_parent(fit)