r - 如何通过 purrr 替换修改 for 循环
问题描述
我想用 purrr 替代品替换一个简单的 for 循环。我该如何编码并保持对象的原始结构
这是我的例子:
my_list <- list(
a = list(
list(
aaa = c(1:3),
aab = c(4:6),
aac = c(7:9)),
list(
aaa = c(10:12),
aab = c(13:15),
aac = c(16:18)),
list(
aaa = c(19:21),
aab = c(22:24),
aac = c(25:27))
))
和我原来的解决方案
x <- purrr::map_lgl(my_list$a, .f = ~ !is.null(.x$aaa))
my_list1 <- my_list
for (i in which(x)) {
my_list1$a[[i]]$aaa <- 99
}
str(my_list1)
但是,我也想用 purrr 解决方案替换我的 for 循环。我尝试过这样的事情,但 map 总是返回一个新列表,而不是仅仅更新它
my_list2 <- map(c(1, 3),
function(x){
my_list[["a"]][[x]][["aab"]] <- 99
return(my_list)
}
)
str(my_list2)
修改在这种情况下应该更适用,但我也不能让它工作。
my_list3 <- purrr::map(
.x = which(x),
.f = function(i = .x) {
purrr::modify_in(.x = my_list,
.where = list("a", i, "aaa"),
.f = ~99)
}
)
str(my_list3)
新列表的结构应该与初始列表相同:
# str(my_list)
List of 1
$ a:List of 3
..$ :List of 3
.. ..$ aaa: int [1:3] 1 2 3
.. ..$ aab: int [1:3] 4 5 6
.. ..$ aac: int [1:3] 7 8 9
..$ :List of 2
.. ..$ aab: int [1:3] 13 14 15
.. ..$ aac: int [1:3] 16 17 18
..$ :List of 3
.. ..$ aaa: int [1:3] 19 20 21
.. ..$ aab: int [1:3] 22 23 24
.. ..$ aac: int [1:3] 25 26 27
# str(my_list1) is correct
List of 1
$ a:List of 3
..$ :List of 3
.. ..$ aaa: num 99
.. ..$ aab: int [1:3] 4 5 6
.. ..$ aac: int [1:3] 7 8 9
..$ :List of 2
.. ..$ aab: int [1:3] 13 14 15
.. ..$ aac: int [1:3] 16 17 18
..$ :List of 3
.. ..$ aaa: num 99
.. ..$ aab: int [1:3] 22 23 24
.. ..$ aac: int [1:3] 25 26 27
# str(my_list2) or str (my_list3) is not correct
List of 2
$ :List of 1
..$ a:List of 3
.. ..$ :List of 3
.. .. ..$ aaa: num 99
.. .. ..$ aab: int [1:3] 4 5 6
.. .. ..$ aac: int [1:3] 7 8 9
.. ..$ :List of 2
.. .. ..$ aab: int [1:3] 13 14 15
.. .. ..$ aac: int [1:3] 16 17 18
.. ..$ :List of 3
.. .. ..$ aaa: int [1:3] 19 20 21
.. .. ..$ aab: int [1:3] 22 23 24
.. .. ..$ aac: int [1:3] 25 26 27
$ :List of 1
..$ a:List of 3
.. ..$ :List of 3
.. .. ..$ aaa: int [1:3] 1 2 3
.. .. ..$ aab: int [1:3] 4 5 6
.. .. ..$ aac: int [1:3] 7 8 9
.. ..$ :List of 2
.. .. ..$ aab: int [1:3] 13 14 15
.. .. ..$ aac: int [1:3] 16 17 18
.. ..$ :List of 3
.. .. ..$ aaa: num 99
.. .. ..$ aab: int [1:3] 22 23 24
.. .. ..$ aac: int [1:3] 25 26 27
有什么提示我在 purrr 上出错了吗?
解决方案
鉴于要修改的列表组件位于第二个嵌套级别,您还可以使用以下命令直接访问它们modify_depth
:
library(purrr)
my_list <- modify_depth(my_list, 2, ~list_modify(.x, aaa = 99))
str(my_list)
#> List of 1
#> $ a:List of 3
#> ..$ :List of 3
#> .. ..$ aaa: num 99
#> .. ..$ aab: int [1:3] 4 5 6
#> .. ..$ aac: int [1:3] 7 8 9
#> ..$ :List of 3
#> .. ..$ aaa: num 99
#> .. ..$ aab: int [1:3] 13 14 15
#> .. ..$ aac: int [1:3] 16 17 18
#> ..$ :List of 3
#> .. ..$ aaa: num 99
#> .. ..$ aab: int [1:3] 22 23 24
#> .. ..$ aac: int [1:3] 25 26 27
注意:这也适用于第一个列表级别的多个列表组件(例如$a
,,$b
...),而无需添加额外的迭代步骤。
编辑:如以下文档中所列modify_depth
:
modify_depth(x, 2, fun) 等价于 x <- modify(x, ~ modify(., fun))
为了仅替换第二个嵌套级别上的列表组件选择,我们可以以modify_depth
更详细的方式将调用重写为:
library(purrr)
## replace aaa only for components 1 and 3
modify_loc <- c(TRUE, FALSE, TRUE)
my_list <- modify(my_list, ~imodify(., ~if(modify_loc[.y]) list_modify(.x, aaa = 99) else .x))
str(my_list)
#> List of 1
#> $ a:List of 3
#> ..$ :List of 3
#> .. ..$ aaa: num 99
#> .. ..$ aab: int [1:3] 4 5 6
#> .. ..$ aac: int [1:3] 7 8 9
#> ..$ :List of 3
#> .. ..$ aaa: int [1:3] 10 11 12
#> .. ..$ aab: int [1:3] 13 14 15
#> .. ..$ aac: int [1:3] 16 17 18
#> ..$ :List of 3
#> .. ..$ aaa: num 99
#> .. ..$ aab: int [1:3] 22 23 24
#> .. ..$ aac: int [1:3] 25 26 27
推荐阅读
- r - 如何将聊天数据向量转换为数据框或矩阵
- python - 在左右(顶部和底部)启用散景 y (x) 轴刻度
- python - 在 Python 中读取 CSV 时出现 ValueError
- c# - 并发发送多个请求时等待 REST 调用完成的死锁问题
- c++ - 如何定义一些可以从(+)运算符的运算符重载范围内访问的函数?
- shell - 为什么使用“./”和“bash”运行脚本结果不同?
- flutter - Flutter:从手机图库中预览一张或多张图片?
- php - 在foreach循环内以小时为单位获取两个日期之间的差异
- php - 有没有理由用自己的元素之一覆盖数组变量?
- facebook-graph-api - ID 为“”的 Facebook 对象不存在 - 用于公开的现有图片