R 从字符串创建嵌套列表结构
我有一个由n个子字符串组成的字符串。它可能是这样的:R 从字符串创建嵌套列表结构,r,string,list,R,String,List,我有一个由n个子字符串组成的字符串。它可能是这样的: string <- c("A_AA", "A_BB", "A_BB_AAA", "B_AA", "B_BB", "B_CC") list("A" = list("AA", "BB" = list("AAA")), "B" = list("AA", "BB", "CC")) > $A $A[[1]] [1] "AA" $A$BB $A$BB[[1]] [1] "CCC" $B $B[[1]]
string <- c("A_AA", "A_BB", "A_BB_AAA", "B_AA", "B_BB", "B_CC")
list("A" = list("AA", "BB" = list("AAA")),
"B" = list("AA", "BB", "CC"))
> $A
$A[[1]]
[1] "AA"
$A$BB
$A$BB[[1]]
[1] "CCC"
$B
$B[[1]]
[1] "AA"
$B[[2]]
[1] "BB"
$B[[3]]
[1] "CC"
非常感谢您在这方面的任何帮助您可以将其制作成矩阵,而无需太多麻烦
string <- c("A_AA", "A_BB", "A_BB_AAA", "B_AA", "B_BB", "B_CC")
splitted<-strsplit(string,"_")
cols<-max(lengths(splitted))
mat<-do.call(rbind,lapply(splitted, "length<-", cols))
string不是那么直截了当,也不是最漂亮的代码,但它应该完成它的工作并返回一个列表:
string <- c("A_AA", "A_BB", "A_BB_AAA", "B_AA", "B_BB", "B_CC")
# loop through each element of the string "str_el"
list_els <- lapply(string, function(str_el) {
# split the string into parts
els <- strsplit(str_el, "_")[[1]]
# loop backwards through the elements
for (i in length(els):1){
# the last element gives the value
if (i == length(els)){
# assign the value to a list and rename the list
res <- list(els[[i]])
names(res) <- els[[i - 1]]
} else {
# if its not the last element (value) assign the list res to another list
# with the name of that element
if (i != 1) {
res <- list(res)
names(res) <- els[[i - 1]]
}
}
}
return(res)
})
# combine the lists into one list
res_list <- mapply(c, list_els, SIMPLIFY = F)
res_list
# [[1]]
# [[1]]$A
# [1] "AA"
#
#
# [[2]]
# [[2]]$A
# [1] "BB"
#
#
# [[3]]
# [[3]]$A
# [[3]]$A$BB
# [1] "AAA"
#
#
#
# [[4]]
# [[4]]$B
# [1] "AA"
#
#
# [[5]]
# [[5]]$B
# [1] "BB"
#
#
# [[6]]
# [[6]]$B
# [1] "CC"
string我找到了这个方法。这很奇怪,但似乎有效
my_relist <- function(x){
y=list()
#This first loop creates the skeleton of the list
for (name in x){
split=strsplit(name,'_',fixed=TRUE)[[1]]
char='y'
l=length(split)
for (i in 1:(l-1)){
char=paste(char,'$',split[i],sep="")
}
char2=paste(char,'= list()',sep="")
#Example of char2: "y$A$BB=list()"
eval(parse(text=char2))
#Evaluates the expression inside char2
}
#The second loop fills the list with the last element
for (name in x){
split=strsplit(name,'_',fixed=TRUE)[[1]]
char='y'
l=length(split)
for (i in 1:(l-1)){
char=paste(char,'$',split[i],sep="")
}
char3=paste(char,'=c(',char,',split[l])')
#Example of char3: "y$A = c(y$A,"BB")"
eval(parse(text=char3))
}
return(y)
}
my\u relist您可以用length(x)
替换lappy(x,length)
,并且,还可以使用do.call(rbind,lappy(splited),length,这会导致与OP想要的结构非常不同的结构。除非有一个从矩阵到OP格式的简单转换,否则我不认为这是他们想要的(我不这么认为)。@KonradRudolph OP确实优先选择列表列表,但似乎对其他结构很灵活。感谢您的努力,但我认为矩阵格式对我来说不是很有用。我需要使用生成的对象来确定a“节点下有多少子/孙节点“。我不确定这在矩阵中是否容易实现(很抱歉从一开始就不清楚这一点)@user3393472使用矩阵实际上比列表容易得多。当你在列表上做length
时,它将同样是列表的元素视为1,它不会计算列表中的所有子元素。而使用矩阵你可以做子集(mat,mat[,1]=“a”)
然后数一数哪一代的列中有多少是na。谢谢,它非常接近。对于我的问题,列表[[1]]必须给我一个完整的“节点”对于所有的孩子和孙子来说,这似乎是****的一个真正的痛苦。你能详细说明一下你想要实现的目标吗。我会坚持@Dean的答案,使用一些非列表结构。列表在某些情况下确实有用,但嵌套列表并不是那么有趣。我现在坚持Dean的解决方案。谢谢或者你的努力。
example <- c("A_AA_AAA", "A_BB", "A_BB_AAA", "B_AA", "B_BB", "B_CC")
my_relist(example)
#$A
#$BB
#1.'AAA'
#[[2]]
#'AA'
#[[3]]
#'BB'
#$B
#1.'AA'
#2.'BB'
#3.'CC'