【问题标题】:Find the indices of an element in a nested list?在嵌套列表中查找元素的索引?
【发布时间】:2013-01-17 07:44:16
【问题描述】:

我有一个类似的列表:

mylist <- list(a = 1, b = list(A = 1, B = 2), c = list(C = 1, D = 3))

是否有一种(无循环)方法来识别元素的位置,例如如果我想用 5 替换“C”的值,并且找到元素“C”并不重要,我可以这样做:

Aindex <- find_index("A", mylist)
mylist[Aindex] <- 5

我已经尝试过grepl,在当前示例中,以下将起作用:

mylist[grepl("C", mylist)][[1]][["C"]]

但这需要假设嵌套级别。

我问的原因是我有一个很深的参数值列表和一个替换值的命名向量,我想做类似的事情

 replacements <- c(a = 1, C = 5)
 for(i in names(replacements)){ 
    indx <- find_index(i, mylist)
    mylist[indx] <-  replacements[i]
  }

这是对我之前的问题update a node (of unknown depth) using xpath in R? 的改编,使用 R 列表而不是 XML

【问题讨论】:

    标签: r list recursion nested


    【解决方案1】:

    一种方法是使用unlistrelist

    mylist <- list(a = 1, b = list(A = 1, B = 2), c = list(C = 1, D = 3))
    tmp <- as.relistable(mylist)
    tmp <- unlist(tmp)
    tmp[grep("(^|.)C$",names(tmp))] <- 5
    tmp <- relist(tmp)
    

    因为来自 unlist 的列表名称与 . 连接,所以您需要小心 grep 以及参数的命名方式。如果您的任何列表名称中都没有.,这应该没问题。否则,list(.C = 1) 之类的名称将落入该模式并被替换。

    【讨论】:

      【解决方案2】:

      基于this question,您可以像这样递归地尝试:

      find_and_replace <- function(x, find, replace){
        if(is.list(x)){
          n <- names(x) == find
          x[n] <- replace
          lapply(x, find_and_replace, find=find, replace=replace)
        }else{
          x
        }
      }
      

      在更深的mylist中测试:

      mylist <- list(a = 1, b = list(A = 1, B = 2), c = list(C = 1, D = 3, d = list(C=10, D=55)))
      find_and_replace(mylist, "C", 5)
      $a
      [1] 1
      
      $b
      $b$A
      [1] 1
      
      $b$B
      [1] 2
      
      
      $c
      $c$C  ### it worked
      [1] 5
      
      $c$D
      [1] 3
      
      $c$d
      $c$d$C ### it worked
      [1] 5
      
      $c$d$D
      [1] 55
      

      【讨论】:

        【解决方案3】:

        这现在也可以使用rrapply-package 中的rrapply 来完成(基础rapply 的扩展版本)。要根据名称返回嵌套列表中元素的位置,我们可以使用特殊参数.xpos.xname。例如,查找名称为"C" 的元素的位置:

        library(rrapply)
        
        mylist <- list(a = 1, b = list(A = 1, B = 2), c = list(C = 1, D = 3))
        
        ## get position C-node
        (Cindex <- rrapply(mylist, condition = function(x, .xname) .xname == "C", f = function(x, .xpos) .xpos, how = "unlist"))
        #> c.C1 c.C2 
        #>    3    1
        

        然后我们可以在嵌套列表中更新它的值:

        ## update value C-node
        mylist[[Cindex]] <- 5
        

        这两个步骤也可以直接在rrapply的调用中合并:

        rrapply(mylist, condition = function(x, .xname) .xname == "C", f = function(x) 5, how = "replace")
        #> $a
        #> [1] 1
        #> 
        #> $b
        #> $b$A
        #> [1] 1
        #> 
        #> $b$B
        #> [1] 2
        #> 
        #> 
        #> $c
        #> $c$C
        #> [1] 5
        #> 
        #> $c$D
        #> [1] 3
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-02-29
          • 1970-01-01
          • 2011-01-25
          • 1970-01-01
          • 2023-02-04
          • 1970-01-01
          • 2019-02-21
          • 1970-01-01
          相关资源
          最近更新 更多