简体   繁体   English

R:根据字符向量中的ID创建嵌套列表

[英]R: Create nested list from IDs in character vector

I have a character vector of hierarchical IDs like this one: 我有一个像这样的层次结构ID的字符向量:

ids <- c("0","1","2","3","1.1","1.2","1.3","2.1","2.2","2.11","2.21","2.22")

The hierarchical structure is as follows: 层次结构如下:

1
    1.1
    1.2
    1.3
2
    2.1
        2.11
    2.2
        2.21
        2.22

I want to use diagonalNetwork() from the networkD3 package to visualize this hierarchy. 我想使用networkD3包中的diagonalNetwork()来可视化此层次结构。 But diagonalNetwork() requires a nested list defining each nodes children like this one: 但是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")
                          )
                     )
                   )
              )
            )
)

My actual set of ids is much larger and deeper (up to 6 digits long), so I need a way to create this nested list automatically. 我的实际ID集更大,更深(最长6位数字),因此我需要一种自动创建此嵌套列表的方法。 I started with creating a data.frame that stores the ids' digits in several columns like this one: 我首先创建一个data.frame,将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))

But I can't think of a way to get any further with my concern. 但我想不出一种进一步解决我的问题的方法。 Is there a more promising approach? 有没有更有前途的方法?

Here is a possible solution based on recursive function. 这是基于递归函数的可能解决方案。 And it is by no means a fast solution but should work for you. 这绝不是一个快速的解决方案,而是应该为您服务。

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)

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM