2

R 中是否有一种优雅的方法可以递归地将任意深度列表(包含列表和向量)转换为路径向量?例如,将其转换为:

list(
  home = list(
    jerry = c("R", "bla"),
    mary = "xx"
  ),
  tmp = c("foo", "bar"),
  c("etc")
)

对于这样的对象:

c(
  "/home/jerry/R",
  "/home/jerry/bla",
  "/home/mary/xx",
  "/tmp/foo",
  "/tmp/bar",
  "/etc"
 )
4

3 回答 3

4

只要您的列表元素中没有一个名称包含点(并且列表中那个麻烦的NULL-valuedetc元素除外),这应该可以工作:

ll <- rapply(l, function(X) sapply(X,list), how="replace") #for tip element names
nms <- names(unlist(ll))
gsub(".", "/", nms, fixed=TRUE)
# [1] "home/jerry/R"   "home/jerry/bla" "home/mary/xx"   "tmp/foo"       
# [5] "tmp/bar"    
于 2013-05-21T20:56:41.840 回答
3

对于更通用的方法,包括可能带有点和空元素的名称,请使用:

f <- function(test, parent=character(0))
{
    if( is.null(test) ) return(parent)

    if( is.list(test) )
    {
        result <- character(0)

        for( i in seq_along(test) )
        {
            result <- c(result, Recall(test[[i]], parent=paste0(parent,"/",names(test)[i])))
        }
    }
    else
    {
        result <- paste0(parent,"/",as.character(test))
    }

    result
}

f(test)

#[1] "/home/jerry/R"   "/home/jerry/bla" "/home/mary/xx"   "/tmp/foo"        "/tmp/bar"        "/etc" 
于 2013-05-21T21:23:01.933 回答
1

中的名称unlist大致符合您的要求:

> test <- list(
+     home = list(
+         jerry = c("R", "bla"),
+         mary = "xx"
+     ),
+     tmp = c("foo", "bar"),
+     etc = c()
+ )
> unlist(test)
home.jerry1 home.jerry2   home.mary        tmp1        tmp2 
        "R"       "bla"        "xx"       "foo"       "bar" 

也处理多级递归:

> test <- list(
+     home = list(
+         jerry = list(a="R", b="bla"),
+         mary = list(c="xx")
+     ),
+     tmp = list(d="foo", e="bar"),
+     etc = list(nothing=NULL)
+ )
> unlist(test)
home.jerry.a home.jerry.b  home.mary.c        tmp.d        tmp.e 
         "R"        "bla"         "xx"        "foo"        "bar" 

从那里很容易添加你想要的最后一点(最终值是最后一个路径元素):

> unl <- unlist(test)
> res <- names(unl)
> res <- paste(res,unl,sep=".")
> res
[1] "home.jerry.a.R"   "home.jerry.b.bla" "home.mary.c.xx"   "tmp.d.foo"        "tmp.e.bar"       
于 2013-05-21T20:44:52.637 回答