我有一个列表:
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
答案 0 :(得分:7)
一种方法是使用unlist
和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中的列表名称与.
连接在一起,因此您需要注意grep
以及参数的命名方式。如果您的任何列表名称中没有.
,这应该没问题。否则,list(.C = 1)
之类的名称将落入模式并被替换。
答案 1 :(得分:1)
基于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
答案 2 :(得分:0)
现在也可以使用rrapply
软件包(基础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