在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"
)
答案 0 :(得分:4)
只要您的列表元素都没有包含点的名称(除了列表中那个有问题的NULL
- 值etc
元素),这应该有效:
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"
答案 1 :(得分: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"
答案 2 :(得分: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"
从那里可以很容易地添加你想要的最后一点(最终值是最后一个路径elemtn):
> 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"