Привет, я в настоящее время пытаюсь извлечь часть информации родительского узла, хранящейся в объекте party, например ID. На данный момент я могу получить идентификаторы терминальных узлов, используя:
fit<-rpart(CommuteDistance ~.,data = Clients)
pr<-as.party(fit)
nodeids(pr,terminal=TRUE)
Но как мне получить родительские идентификаторы? И если возможно, как я могу получить имена узлов?





Нет доступной функции для удобного извлечения этого. Но нетрудно просто пройти через рекурсивную структуру 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 (если есть). Таким образом, мы можем легко извлечь их с помощью 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 и т. д.
Поскольку идентификаторы узлов следуют красивому шаблону, вы можете определить родительский идентификатор просто по parent_id = floor (node_id / 2).
Вот минимальный рабочий пример для получения таблицы с отображением идентификаторов узлов на их родительские идентификаторы. В нем я использую функцию rownames_to_column из tidyverse, чтобы получить 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
Получить имена узлов можно с помощью меток (fit)
Для минимального рабочего примера, объединяющего эти две вещи, чтобы получить таблицу, содержащую идентификаторы узлов, метки узлов, родительские идентификаторы и родительские метки:
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)
Я знаю, что это старая ветка, но я наткнулся на это через поиск в Google, и, не имея принятого ответа, я подумал, что это может помочь кому-то еще в будущем.