R 想要一个递归函数,它对参数进行编号,递归到列表中

R 想要一个递归函数,它对参数进行编号,递归到列表中,r,recursion,R,Recursion,假设我有一份清单 l<-list(a="",b="",c=list(d="",e=list(f=""),g="")) 现在我想根据列表的顺序为最后的字符向量赋值。例如,l$a的值为1,l$c$d的值为3.1,l$c$e$f的值为3.2.1。 我创建了一个递归函数来生成和分配值: sequencize<-function(list,loopn="1"){ if(!is.list(list)){ list<-loopn }else{ for(i in

假设我有一份清单

l<-list(a="",b="",c=list(d="",e=list(f=""),g=""))  
现在我想根据列表的顺序为最后的字符向量赋值。例如,l$a的值为1,l$c$d的值为3.1,l$c$e$f的值为3.2.1。 我创建了一个递归函数来生成和分配值:

sequencize<-function(list,loopn="1"){
  if(!is.list(list)){
    list<-loopn
  }else{
    for(i in 1:length(list)){
      sublist<-list[[i]]
      newloopn<-paste(loopn,i,sep=".")
      sequencize(sublist,newloopn)
    }
  }
  list
}
但是,当我运行sequencizel时,它返回一个与输入相同的列表,没有为向量赋值。
有人能告诉我我的函数有什么问题吗?

您需要确保在递归函数中实际构造并返回一个新列表:

sequencize <- function(list, loopn="1") {
  if (!is.list(list)){
    loopn
  } else {
    l <- lapply(1:length(list), function(i) sequencize(list[[i]], paste(loopn,i,sep=".")))
    names(l) <- names(list)
    l
  }
}
str(sequencize(l))
# List of 3
#  $ a: chr "1.1"
#  $ b: chr "1.2"
#  $ c:List of 3
#   ..$ d: chr "1.3.1"
#   ..$ e:List of 1
#   .. ..$ f: chr "1.3.2.1"
#   ..$ g: chr "1.3.3"

在阅读了回复并挣扎了一天之后,我终于明白了问题所在,并找到了解决方案:

sequencize<-function(lst,loopn="1"){
        if(!is.list(lst)){
                lst<-loopn
        }else{
                for(i in 1:length(lst)){
                        lst[[i]]<-sequencize(lst[[i]],paste(loopn,i,sep="."))
                }
                lst
        }
}

> str(sequencize(l))
List of 3
 $ a: chr "1.1"
 $ b: chr "1.2"
 $ c:List of 3
  ..$ d: chr "1.3.1"
  ..$ e:List of 1
  .. ..$ f: chr "1.3.2.1"
  ..$ g: chr "1.3.3"

for循环不返回任何内容。所有这些要求顺序化的呼吁基本上都被抛弃了。你想用它们做什么。另外,您没有更改else块中list的值,list是函数返回的值。。。因此,不要在它后面命名一个变量来隐藏它!对不起,@smci,我不明白你的意思。你所说的不在它后面命名变量是什么意思?你能详细解释一下吗?我不是以英语为母语的人:。如果在启动R时键入list,您会看到它是一个函数。基本列表。不要在函数中隐藏该定义,将其重新定义为函数参数之一:functionlist。。。list@smci,明白了,谢谢!感谢您和@MrFlick的及时回复!我接受了你的回答,思考了一会儿;然而,我仍然不太确定到底出了什么问题。在我看来,虽然for循环本身不返回任何东西,但是if块返回值,当函数递归到末尾时,它肯定会命中if块,对吗?我的逻辑错了吗,还是与R中的某些机制有关?我对R比较陌生,没有任何其他编程语言的经验,因此希望您能提供更多信息@在if语句的else部分,您进行递归调用,但从不将结果存储在任何地方。因此,当您在末尾返回列表时,它将返回原始列表。
sequencize<-function(lst,loopn="1"){
        if(!is.list(lst)){
                lst<-loopn
        }else{
                for(i in 1:length(lst)){
                        lst[[i]]<-sequencize(lst[[i]],paste(loopn,i,sep="."))
                }
                lst
        }
}

> str(sequencize(l))
List of 3
 $ a: chr "1.1"
 $ b: chr "1.2"
 $ c:List of 3
  ..$ d: chr "1.3.1"
  ..$ e:List of 1
  .. ..$ f: chr "1.3.2.1"
  ..$ g: chr "1.3.3"