编辑:我重写了这个问题,因为我有两个相关的问题可能会更好地一起回答......
我有一些大型嵌套list
,结构几乎相同,没有名字。 list
的所有项目都有attr
个ibutes,我想在list
的所有级别中将这些项目指定为名称。此外,我想删除一个不必要的列表级别。
所以这个:
before <- list(list("value_1"), list(list("value_2a"), list("value_2b")), list(list("value_3a"), list("value_3b"), list("value_3c")), list("value_4"))
for(i in 1:4) attr(before[[i]], "tag") <- paste0("tag_", i)
attr(before[[2]][[1]], "code") <- "code_2a"
attr(before[[2]][[2]], "code") <- "code_2b"
attr(before[[3]][[1]], "code") <- "code_3a"
attr(before[[3]][[2]], "code") <- "code_3b"
attr(before[[3]][[3]], "code") <- "code_3c"
str(before)
## List of 4
## $ :List of 1
## ..$ : chr "value_1"
## ..- attr(*, "tag")= chr "tag_1"
## $ :List of 2
## ..$ :List of 1
## .. ..$ : chr "value_2a"
## .. ..- attr(*, "code")= chr "code_2a"
## ..$ :List of 1
## .. ..$ : chr "value_2b"
## .. ..- attr(*, "code")= chr "code_2b"
## ..- attr(*, "tag")= chr "tag_2"
## $ :List of 3
## ..$ :List of 1
## .. ..$ : chr "value_3a"
## .. ..- attr(*, "code")= chr "code_3a"
## ..$ :List of 1
## .. ..$ : chr "value_3b"
## .. ..- attr(*, "code")= chr "code_3b"
## ..$ :List of 1
## .. ..$ : chr "value_3c"
## .. ..- attr(*, "code")= chr "code_3c"
## ..- attr(*, "tag")= chr "tag_3"
## $ :List of 1
## ..$ : chr "value_4"
## ..- attr(*, "tag")= chr "tag_4"
(注意:第一级列表项具有“标记” - 属性,第二级项目具有“代码” - 属性。)
应该是这样的:
after <- list(tag_1="value_1", tag_2=list(code_2a="value_2a", code_2b="value_2b"), tag_3=list(code_3a="value_3a", code_3b="value_3b", code_3c="value_3c"), tag_4="value_4")
str(after)
## List of 4
## $ tag_1: chr "value_1"
## $ tag_2:List of 2
## ..$ code_2a: chr "value_2a"
## ..$ code_2b: chr "value_2b"
## $ tag_3:List of 3
## ..$ code_3a: chr "value_3a"
## ..$ code_3b: chr "value_3b"
## ..$ code_3c: chr "value_3c"
## $ tag_4: chr "value_4"
由于列表很大,我想避免for
循环,以获得更好的性能。
答案 0 :(得分:0)
您可以通过在列表中递归来轻松完成此操作。试试这个:
setListNames <- function(mylist){
# Base case: if we have a nonlist object, set name to its attribute
if( !is.list(mylist) ){
names( mylist ) = attr(mylist, 'code')
return( mylist )
}
# lapply through all sublists and recursively call
mylist = lapply(mylist, setListNames)
# Return named list
return( mylist )
}
# Test run
before_named = setListNames(before)
# Check it worked
print( names( before_named[[2]][[1]][[1]] ) )
答案 1 :(得分:0)
知道了!三个步骤,但效果很好。
# the ugly list
ugly_list <- list(list("value_1"), list(list("value_2a"), list("value_2b")), list(list("value_3a"), list("value_3b"), list("value_3c")), list("value_4"))
for(i in 1:4) attr(ugly_list[[i]], "tag") <- paste0("tag_", i)
attr(ugly_list[[2]][[1]], "code") <- "code_2a"
attr(ugly_list[[2]][[2]], "code") <- "code_2b"
attr(ugly_list[[3]][[1]], "code") <- "code_3a"
attr(ugly_list[[3]][[2]], "code") <- "code_3b"
attr(ugly_list[[3]][[3]], "code") <- "code_3c"
# set names for 1st level
level_1_named <- setNames(ugly_list, sapply(ugly_list, function(x) attributes(x)$tag))
# set names for 2nd level
level_2_named <- lapply(level_1_named, function(x) lapply(x, function(y) setNames(y, attributes(y)$code)))
# clean list
clean_list <- lapply(level_2_named, function(x) unlist(x, recursive=FALSE))
感谢您的努力。 : - )