gpt4 book ai didi

r - 将数据框转换为 treeNetwork 兼容列表

转载 作者:行者123 更新时间:2023-12-04 07:52:38 24 4
gpt4 key购买 nike

考虑以下数据框:

   Country     Provinces          City Zone
1 Canada Newfondland St Johns A
2 Canada PEI Charlottetown B
3 Canada Nova Scotia Halifax C
4 Canada New Brunswick Fredericton D
5 Canada Quebec NA NA
6 Canada Quebec Quebec City NA
7 Canada Ontario Toronto A
8 Canada Ontario Ottawa B
9 Canada Manitoba Winnipeg C
10 Canada Saskatchewan Regina D

是否有一种巧妙的方法将其转换为 treeNetwork兼容列表(来自 networkD3 包),格式为:
CanadaPC <- list(name = "Canada",
children = list(
list(name = "Newfoundland",
children = list(list(name = "St. John's",
children = list(list(name = "A"))))),
list(name = "PEI",
children = list(list(name = "Charlottetown",
children = list(list(name = "B"))))),
list(name = "Nova Scotia",
children = list(list(name = "Halifax",
children = list(list(name = "C"))))),
list(name = "New Brunswick",
children = list(list(name = "Fredericton",
children = list(list(name = "D"))))),
list(name = "Quebec",
children = list(list(name = "Quebec City"))),
list(name = "Ontario",
children = list(list(name = "Toronto",
children = list(list(name = "A"))),
list(name = "Ottawa",
children = list(list(name = "B"))))),
list(name = "Manitoba",
children = list(list(name = "Winnipeg",
children = list(list(name = "C"))))),
list(name = "Saskatchewan",
children = list(list(name = "Regina",
children = list(list(name = "D")))))))

为了绘制具有任意级别集的 Reingold-Tilford 树:

enter image description here

我尝试了几个次优例程,包括 for 的困惑组合。循环,但我无法以所需的格式获得它。

理想情况下,该函数会缩放以将第一列视为 root (起点)和其他列将是不同级别的 child 。

编辑

一个 similar question被问到同一主题,@MrFlick 提供了一个有趣的递归函数。原始数据框有一组固定的级别。我介绍 NA s 以添加@MrFlick 初始解决方案中 Unresolved 另一个复杂级别(任意级别集)。

数据
structure(list(Country = c("Canada", "Canada", "Canada", "Canada", 
"Canada", "Canada", "Canada", "Canada", "Canada", "Canada"),
Provinces = c("Newfondland", "PEI", "Nova Scotia", "New Brunswick",
"Quebec", "Quebec", "Ontario", "Ontario", "Manitoba", "Saskatchewan"
), City = c("St Johns", "Charlottetown", "Halifax", "Fredericton",
NA, "Quebec City", "Toronto", "Ottawa", "Winnipeg", "Regina"
), Zone = c("A", "B", "C", "D", NA, NA, "A", "B", "C",
"D")), class = "data.frame", row.names = c(NA, -10L), .Names = c("Country",
"Provinces", "City", "Zone"))

最佳答案

对于这种情况,更好的策略可能是递归 split()这是一个这样的实现。首先,这是示例数据

dd<-structure(list(Country = c("Canada", "Canada", "Canada", "Canada", 
"Canada", "Canada", "Canada", "Canada", "Canada", "Canada"),
Provinces = c("Newfondland", "PEI", "Nova Scotia", "New Brunswick",
"Quebec", "Quebec", "Ontario", "Ontario", "Manitoba", "Saskatchewan"
), City = c("St Johns", "Charlottetown", "Halifax", "Fredericton",
NA, "Quebec City", "Toronto", "Ottawa", "Winnipeg", "Regina"
), Zone = c("A", "B", "C", "D", NA, NA, "A", "B", "C",
"D")), class = "data.frame", row.names = c(NA, -10L), .Names = c("Country",
"Provinces", "City", "Zone"))

请注意,'我已经替换了 "NA"字符串为真 NA值。现在,函数
rsplit <- function(x) {
x <- x[!is.na(x[,1]),,drop=FALSE]
if(nrow(x)==0) return(NULL)
if(ncol(x)==1) return(lapply(x[,1], function(v) list(name=v)))
s <- split(x[,-1, drop=FALSE], x[,1])
unname(mapply(function(v,n) {if(!is.null(v)) list(name=n, children=v) else list(name=n)}, lapply(s, rsplit), names(s), SIMPLIFY=FALSE))
}

然后我们可以运行
rsplit(dd)

它似乎适用于测试数据。唯一的区别是子节点的排列顺序。

关于r - 将数据框转换为 treeNetwork 兼容列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30734572/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com