繁体   English   中英

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

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

我有一个像这样的层次结构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

我想使用networkD3包中的diagonalNetwork()来可视化此层次结构。 但是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位数字),因此我需要一种自动创建此嵌套列表的方法。 我首先创建一个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))

但我想不出一种进一步解决我的问题的方法。 有没有更有前途的方法?

这是基于递归函数的可能解决方案。 这绝不是一个快速的解决方案,而是应该为您服务。

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