8

我有一个类似的列表:

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]
  }

这是对我之前的问题的改编,在 R 中使用 xpath 更新节点(深度未知)?,使用 R 列表而不是 XML

4

3 回答 3

8

一种方法是使用unlistand relist

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 中的列表名称与 a 连接,所以.您需要注意grep参数的命名方式和命名方式。如果您的任何列表名称中都没有 a .,那应该没问题。否则,名称 likelist(.C = 1)将落入模式并被替换。

于 2013-02-01T22:45:49.313 回答
1

基于这个问题,您可以像这样递归地尝试它:

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
于 2014-10-02T14:32:27.863 回答
0

这现在也可以rrapplyrrapply-package (base 的扩展版本rapply)中使用。要根据名称返回嵌套列表中元素的位置,我们可以使用特殊参数.xpos.xname。例如,要查找具有 name 的元素的位置"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
于 2020-06-13T08:15:59.337 回答