使用深度名称向量作为索引替换嵌套列表

问题描述 投票:0回答:3

取一个简单的嵌套列表

L

L <- list(lev1 = list(lev2 = c("bit1","bit2")), other=list(yep=1))
L
#$lev1
#$lev1$lev2
#[1] "bit1" "bit2"
#
# 
#$other
#$other$yep
#[1] 1

还有一个向量,为我想从中选择的每个部分提供一系列深度

L

sel <- c("lev1","lev2")

索引时我想要的结果是:

L[["lev1"]][["lev2"]]
#[1] "bit1" "bit2"

我可以像这样使用

Reduce
来概括:

Reduce(`[[`, sel, init=L)
#[1] "bit1" "bit2"

现在,我想扩展这个逻辑来做一个替换,像这样:

L[["lev1"]][["lev2"]] <- "new val"

,但我真的很困惑如何以一种允许我随后分配给它的方式生成递归

[[
选择。

r list nested assign
3个回答
5
投票

为什么你不能做

L[[sel]] <- "new val"

好吧,如果你想走很长的路那么 您仍然可以将

Reduce
modifyList
一起使用,或者您可以使用
[[<-
。这是
modifyList
的例子:

modifyList(L,Reduce(function(x,y)setNames(list(x),y),rev(sel),init = "new val"))
$lev1
$lev1$lev2
[1] "new val"


$other
$other$yep
[1] 1

1
投票

您可以通过连接所有内容来

eval()
parse()
。我不确定你能做到多普遍:

``` r
L <- list(lev1 = list(lev2 = c("bit1","bit2")), other=list(yep=1))
L
#> $lev1
#> $lev1$lev2
#> [1] "bit1" "bit2"
#> 
#> 
#> $other
#> $other$yep
#> [1] 1

sel <- c("lev1","lev2")

eval(parse(text = paste0('L', paste0('[["', sel, '"]]', collapse = ''), '<- "new val"')))

L
#> $lev1
#> $lev1$lev2
#> [1] "new val"
#> 
#> 
#> $other
#> $other$yep
#> [1] 1

创建于 2019-11-25 由 reprex 包 (v0.3.0)


0
投票

使用一系列构建的

call
然后评估:

替换作品:

sel <- c("lev1","lev2")
selexpr <- Reduce(\(x,y) call("[[", x, y), sel, init=quote(L))
## L[["lev1"]][["lev2"]]
eval(call("<-", selexpr, 2))
L
#$lev1
#$lev1$lev2
#[1] 2
#
#
#$other
#$other$yep
#[1] 1

也适用于生成新的列表条目:

sel <- c("new","chunk")
selexpr <- Reduce(\(x,y) call("[[", x, y), sel, init=quote(L))
eval(call("<-", selexpr, "new value"))
L
#$lev1
#$lev1$lev2
#[1] 2
#
#
#$other
#$other$yep
#[1] 1
#
#
#$new
#$new$chunk
#[1] "new value"
© www.soinside.com 2019 - 2024. All rights reserved.