我有一个像这样的分层ID的字符向量:
ids <- c("0","1","2","3","1.1","1.2","1.3","2.1","2.2","2.11","2.21","2.22")
层次结构如下:
1
1.1
1.2
1.3
2
2.1
2.11
2.2
2.21
2.22
我想使用diagonalNetwork()
包中的networkD3
来可视化此层次结构。但diagonalNetwork()
需要一个嵌套列表,定义每个节点的子节点如下:
l <- list(name = "0",
children = list(
list(name = "1",
children = list(
list(name = "1.1"),
list(name = "1.2"),
list(name = "1.3")
)
),
list(name = "2",
children = list(
list(name = "2.1",
children = list(
list(name = "2.11")
)
),
list(name = "2.2",
children = list(
list(name = "2.21"),
list(name = "2.22")
)
)
)
)
)
)
我的实际id组更大更深(最多6位数),所以我需要一种方法来自动创建这个嵌套列表。我开始创建一个存储id的数据框架。像这样的几列中的数字:
df <- data.frame(root = 0,
a = c( 1, 1, 1, 1, 2, 2, 2, 2, 2, 2),
b = c(NA, 1, 2, 3,NA, 1, 1, 2, 2, 2),
c = c(NA,NA,NA,NA,NA,NA, 1,NA, 1, 2))
但我无法想到如何进一步解决我的问题。 有没有更有希望的方法?
答案 0 :(得分:2)
这是一个基于递归函数的可能解决方案。它绝不是一个快速的解决方案,但应该适合你。
library(network3D)
findChildren <- function(pa, ids) {
lapply(ids, function(ch){
if(grepl(paste("^", pa, sep = ""), ch) && ch != pa &&
nchar(gsub("\\.", "", ch)) == nchar(gsub("\\.", "", pa)) + 1)
{
childrenTmp = Filter(Negate(is.null), findChildren(ch, ids))
if(length(childrenTmp) != 0) list(name = ch, children = childrenTmp)
else list(name = ch)
}
}
)
}
myList <- list(name = "0",
children = Filter(
function(x){nchar(x$name) == 1 },
lapply(ids[-1], function(id) {
childrenTmp = Filter(Negate(is.null), findChildren(id, ids))
if(length(childrenTmp) != 0) list(name = id, children = childrenTmp)
else list(name = id)
}
)
)
)
diagonalNetwork(myList)