说,这是我有点复杂和粗糙的清单:
res <- list(
a = TRUE,
b = "error msg 1",
c = list(
TRUE,
"error msg 2"
),
d = list(
e = "error msg 3",
"error msg 4", # no name for this list item just to make things interesting
f = list(
g = list(
h = "error msg 5",
i = TRUE
)
)
)
)
我现在想要在2
深度(从顶部)应用一些功能。
我的名单可以任意深入和粗糙。
我希望自己都很冷静,所以我会这样做:
purrr::modify_depth(.x = res, .depth = 2, .f = str, .ragged = TRUE)
但是,出乎意料的是,
失败了Error in .x[] <- .f(.x, ...) : replacement has length zero
不能对此做出正面或反面,因为当我str()
手动浏览所有列表元素时,它可以正常工作; str()
总能给出一些结果。
我猜我错了.ragged =
。
当我使用is.null()
作为函数而不是str()
时,我也注意到相同的设置有效,但是然后应用于 don't 实际存在(扩展列表)。
purrr::modify_depth(.x = res, .depth = 4, .f = is.null, .ragged = TRUE)
这会创建一个统一 4深的列表,尽管原始版本实际上非常粗糙,只有4个深层 1 分支。
其他未经修改的。
我如何才能n
这样做?
答案 0 :(得分:1)
这是一个古老的问题,但是由于这里缺少令人满意的答案,因此就消失了。
首先,str
将输出显示到终端,但实际上不返回任何内容:
is.null(str("anything"))
#> chr "anything"
#> [1] TRUE
purrr
调用失败,因为.f = str
试图将NULL
的值分配给列表元素,这是不允许的。当前purrr版本(3.4.0)中的错误消息也更清楚地表明了这一点:
purrr::modify_depth(.x = res, .depth = 2, .f = str, .ragged = TRUE)
#> logi TRUE
#> Error: Result 1 must be a single logical, not NULL of length 0
用其他功能代替str
,purrr
不再抱怨:
purrr::modify_depth(.x = res, .depth = 2, .f = is.character, .ragged = TRUE)
#> $a
#> [1] FALSE
#>
#> $b
#> [1] "TRUE"
#>
#> $c
#> $c[[1]]
#> [1] FALSE
#>
#> $c[[2]]
#> [1] TRUE
#>
#>
#> $d
#> $d$e
#> [1] TRUE
#>
#> $d[[2]]
#> [1] TRUE
#>
#> $d$f
#> [1] FALSE
但是,问题仍然存在,modify_depth
恰好在.f
上应用.depth = 2
,因此.f = is.character
会将所有更深层次的子列表折叠为逻辑值
在purrr
程序包(base-rrapply
的扩展版本)中,rrapply
可能是另一个选项(非rrapply
),可以通过嵌套列表进行递归。设置how = "replace"
,我们只能修改特定深度的元素,而其他所有列表元素均保持不变:
library(rrapply)
rrapply(res, condition = function(x, .xpos) length(.xpos) == 2, f = function(x) paste(x, "<- modified"), how = "replace")
#> $a
#> [1] TRUE
#>
#> $b
#> [1] "error msg 1"
#>
#> $c
#> $c[[1]]
#> [1] "TRUE <- modified"
#>
#> $c[[2]]
#> [1] "error msg 2 <- modified"
#>
#>
#> $d
#> $d$e
#> [1] "error msg 3 <- modified"
#>
#> $d[[2]]
#> [1] "error msg 4 <- modified"
#>
#> $d$f
#> $d$f$g
#> $d$f$g$h
#> [1] "error msg 5"
#>
#> $d$f$g$i
#> [1] TRUE
在这里,condition
决定将f
函数应用于哪些列表元素,而.xpos
自变量求值该元素在嵌套列表中的位置作为整数向量。然后length(.xpos)
可用于评估嵌套列表中任何元素的深度。