如何在R中沿树的分支输出值?
给定任何数据帧,如何得到一棵树或一个列表,告诉我R中树的每个分支的值 例如,如果我有一个如下所示的数据帧: Gender Under 18? Student M Y Y F Y Y M N Y M Y Y F N N M N N F N N F Y N M Y N 18岁以下的性别?学生 M Y Y F Y 纽约 M Y Y F N N M N N F N N F Y N M Y N 如何像下面的树一样沿分支输出值 沿分支具有值的树如何在R中沿树的分支输出值?,r,tree,R,Tree,给定任何数据帧,如何得到一棵树或一个列表,告诉我R中树的每个分支的值 例如,如果我有一个如下所示的数据帧: Gender Under 18? Student M Y Y F Y Y M N Y M Y Y F N N M N
通常,决策树是rpart或其他基于树的包的结果,这些包创建决策规则。然后可以使用rpart.plot的
prp
或Crattle的fancyRpartPlot
函数绘制
但基于您的数据集,我创建了一个函数和一组代码(所有这些都可以放入一个大函数中)。Igraph(或diagrammer)可用于绘制决策树。我用过Igraph。运行这个程序所需的其他包是dplyr和tidyr
只要初始表与现有表相同,代码就相对灵活。所以每行都有一个完整的决策路径
第一步创建一个函数来统计每个决策路径的出现次数并添加缺少的决策路径。接下来的两个步骤创建顶点和边标签,这些标签是在节点和顶点上创建文本所需的。此代码中的GROUPBY语句需要确保所有值都位于正确的位置。最后一步是创建一个图形并用边和顶点打印它。本文中的图片是基于您的数据得出的结果。如果您需要不同的顶点标签(如示例中所示),可以执行一些ifelse语句,但这并不能使其具有灵活性。图中显示了基于示例数据的结果
完整代码在图片下方
library(tidyr)
图书馆(dplyr)
图书馆(igraph)
#统计总分组级别上的所有规则
#为每个缺少的路径添加一行0
完成百分比
总结(n=n())%>%
解组%>%
完成(!!!rlang::syms(vars),fill=列表(n=0))##
}
dat%
总结(总计=总和(n))%>%
解组()%>%
拉力(总)
顶点标签%
不同%>%
拉力(i)
edge_标签谢谢@phiver这非常有用:)
library(tidyr)
library(dplyr)
library(igraph)
# count all the rules at the total grouped level
# add a line for each missing path with a 0
complete_df <- function(dat){
vars <- names(dat)
dat %>%
group_by_all %>%
summarise(n = n()) %>%
ungroup %>%
complete(!!!rlang::syms(vars), fill = list(n = 0)) ##
}
dat <- complete_df(df1)
vertex_labels <- sum(dat$n)
for(i in seq_along(dat[, -ncol(dat)])) {
out <- dat %>%
select(1:i, n) %>%
group_by_if(is.character) %>%
summarise(total = sum(n)) %>%
ungroup() %>%
pull(total)
vertex_labels <- c(vertex_labels, out)
}
# labels for inside the nodes
edge_labels <- NULL
for(i in seq_along(dat[, -ncol(dat)])) {
out <- dat %>%
select(1:i) %>%
group_by_if(is.character) %>%
distinct %>%
pull(i)
edge_labels <- c(edge_labels, out)
}
plot(graph.tree(2^(ncol(dat)) - 1, 2),
layout=layout_as_tree,
edge.label = edge_labels,
vertex.label = vertex_labels
)
df1 <- structure(list(Gender = c("M", "F", "M", "M", "F", "M", "F", "F", "M"),
Under_18 = c("Y", "Y", "N", "Y", "N", "N", "N", "Y", "Y"),
Student = c("Y", "Y", "Y", "Y", "N", "N", "N", "N", "N")),
class = "data.frame", row.names = c(NA, -9L))