如何通过 purrr 替换修改 for 循环 [英] How to replace a modifying for loop by purrr

查看:49
本文介绍了如何通过 purrr 替换修改 for 循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用 purrr 替代方案替换一个简单的 for 循环.我该如何编码并保持对象的原始结构

I would like to replace a simple for loop by a purrr alternative. How can I code this and keep the original structure of my object

这是我的例子:

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 循环.我试过这样的事情,但地图总是返回一个新列表,而不是仅仅更新它

However, I would like to replace my for loop by a purrr-solution, as well. I tried something like this, but map always returns a new list instead of just updating it

my_list2 <- map(c(1, 3),
        function(x){
          my_list[["a"]][[x]][["aab"]] <- 99
          return(my_list)
        }
)
str(my_list2)

Modify 应该更适用于这种情况,但我也无法使其工作.

Modify should be more applicable in this context but I could'nt make it work either.

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)

新列表的结构应该与初始列表相同:

The structure of the new list should look the same like the initial list:

# 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

有什么提示我哪里出错了吗?

Any hints where I go wrong with purrr?

推荐答案

一种方法是使用 map 并更改每个列表中的单个元素.

One way would be using map and change a single element in each list.

my_list[["a"]][x] <- purrr::map(my_list[["a"]][x], ~{.[["aaa"]] <- 99;.})


my_list
#$a
#$a[[1]]
#$a[[1]]$aaa
#[1] 99

#$a[[1]]$aab
#[1] 4 5 6

#$a[[1]]$aac
#[1] 7 8 9


#$a[[2]]
#$a[[2]]$aaa
#[1] 99

#$a[[2]]$aab
#[1] 13 14 15

#$a[[2]]$aac
#[1] 16 17 18
#......

这与在基础 R 中使用 lapply 相同

which is same as using lapply in base R

my_list[["a"]][x] <- lapply(my_list[["a"]][x], function(x) {x[["aaa"]] <- 99;x})

这篇关于如何通过 purrr 替换修改 for 循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆