如何基于四级层级树形输入实现DataFrame的四级代码筛选
基于四级树形输入实现DataTable的HS4层级筛选
需求:使用包含四级层级(All product -> category -> HS2 -> HS4 -> HS6)的树形输入对DataTable进行筛选,选中任意父级节点时,DataTable始终基于第四级HS4代码进行筛选。
实现思路
- 捕获树形组件选中节点的完整路径
- 解析路径前缀,匹配数据中所有属于该前缀下的HS4代码
- 用HS4代码集合筛选DataTable数据
修改后的完整代码
library(shiny) library(jsTreeR) library(DT) ui <- fluidPage( dropdownButton( inputId = "mydropdown", label = "Select products", icon = "", status = "primary", circle = FALSE, jstreeOutput("mytree") ), DTOutput("table") ) server <- function(input, output, session) { df <- data.frame( all = c("All product","All product","All product","All product","All product","All product","All product","All product", "All product","All product","All product","All product","All product","All product","All product","All product"), category = c("Agriculture","Agriculture","Agriculture","Agriculture", "Agriculture","Agriculture","Agriculture","Agriculture", "Non Agriculture", "Non Agriculture", "Non Agriculture", "Non Agriculture","Non Agriculture", "Non Agriculture", "Non Agriculture", "Non Agriculture"), HS2 = c("01","01","01","01","02","02","02","02","03","03","03","03","04","04","04","04"), HS4 = c("0101","0101","0102","0102","0201","0201","0202","0202","0301","0301","0302","0302","0401","0401","0402","0402"), HS6 = c("010101","010102", "010201","010202","020101","020102","020201","020202","030101","030102", "030201","030202","040101","040102","040201","040202") ) output$mytree <- renderJstree({ makeNodes <- function(leaves){ dfs <- lapply(strsplit(leaves, "/"), function(s){ item <- Reduce(function(a,b) paste0(a,"/",b), s[-1], s[1], accumulate = TRUE) data.frame( item = item, parent = c("root", item[-length(item)]), stringsAsFactors = FALSE ) }) dat <- dfs[[1]] for(i in 2:length(dfs)){ dat <- merge(dat, dfs[[i]], all = TRUE) } f <- function(parent){ i <- match(parent, dat$item) item <- dat$item[i] children <- dat$item[dat$parent==item] label <- tail(strsplit(item, "/")[[1]], 1) if(length(children)){ list( text = label, children = lapply(children, f), icon =FALSE, state = list(selected = TRUE, opened = FALSE ) ) }else{ list(text = label, type = "child",icon = FALSE, state = list(selected = TRUE,opened = FALSE )) } } lapply(dat$item[dat$parent == "root"], f) } # 转换为路径向量 paths <- apply(df, 1, function(x) paste0(x, collapse = "/")) # 生成节点列表 nodes <- makeNodes(paths) jstree( nodes, checkboxes = TRUE, theme = "proton", checkCallback = JS("$.jstree.defaults.core.expand_selected_onload = false;"), plugins = c("checkbox") ) }) # 处理选中节点,提取对应的HS4代码 selected_HS4 <- reactive({ req(input$mytree_get_selected) selected_paths <- input$mytree_get_selected # 解析每个选中路径,提取前缀,匹配对应的HS4 hs4_list <- lapply(selected_paths, function(path) { path_parts <- strsplit(path, "/")[[1]] # 根据路径长度判断层级,生成匹配条件 if(length(path_parts) == 1){ # 选中All product unique(df$HS4) } else if(length(path_parts) == 2){ # 选中category unique(df$HS4[df$category == path_parts[2]]) } else if(length(path_parts) == 3){ # 选中HS2 unique(df$HS4[df$HS2 == path_parts[3]]) } else if(length(path_parts) == 4){ # 选中HS4 path_parts[4] } else { # 选中HS6,取对应的HS4 unique(df$HS4[df$HS6 == path_parts[5]]) } }) # 去重合并所有HS4 unique(unlist(hs4_list)) }) output$table <- renderDT({ datatable(df[df$HS4 %in% selected_HS4(), ]) }) } shinyApp(ui, server)
关键说明
selected_HS4反应式变量:负责解析选中节点的路径,根据不同层级提取对应的HS4代码集合。比如选中"Agriculture"时,会返回该分类下所有的HS4代码;选中HS2的"01"时,返回该HS2下的HS4代码。- 树形组件配置:保留
checkbox插件,确保选中父节点时子节点自动选中,同时通过input$mytree_get_selected获取完整选中路径。 - DataTable筛选:直接根据提取的HS4集合过滤数据,确保始终基于第四级HS4进行筛选。
内容的提问来源于stack exchange,提问作者akshay bholee
相关产品推荐
相关产品推荐

