Purrr 的修改函数

Purrr's Modify-In Function

我正在尝试使用 purrr 的 modify_in 来修改列表的元素。列表示例:

tib_list <- map(1:3, ~ tibble(col_one = runif(5),
    col_two = runif(5), col_three = runif(5)))

假设我想更改列表的元素 2 和 3 以取消选择 col_one。我想象这样做:

modify_in(tib_list, 2:length(tib_list), ~ select(.x, -col_one) 

但这会产生错误。然后我想做这样的事情,但这最终会复制列表

map(1:3, ~ modify_in(tib_list, .x, ~ select(.x, -col_one)) 

我没用过modify_in,但你可以用

library(purrr)
library(dplyr)

tib_list %>% 
  imap(~ if (.y > 1) { select(.x, -col_one) } else { .x })

获得

[[1]]
# A tibble: 5 x 3
  col_one col_two col_three
    <dbl>   <dbl>     <dbl>
1   0.710   0.189    0.644 
2   0.217   0.946    0.955 
3   0.590   0.770    0.0180
4   0.135   0.101    0.888 
5   0.640   0.645    0.346 

[[2]]
# A tibble: 5 x 2
  col_two col_three
    <dbl>     <dbl>
1   0.267    0.926 
2   0.456    0.0902
3   0.659    0.707 
4   0.421    0.0451
5   0.801    0.220 

[[3]]
# A tibble: 5 x 2
  col_two col_three
    <dbl>     <dbl>
1   0.437     0.649
2   0.256     0.466
3   0.331     0.594
4   0.586     0.558
5   0.625     0.444

我认为您想使用 modify_at 来指定元素名称或位置。 modify_in 允许我们只使用一个位置,如 purrr::pluck.

library(tidyverse)

tib_list <- map(1:3, ~ tibble(col_one = runif(5), col_two = runif(5), col_three = runif(5)))

modify_at(tib_list, c(2,3), ~ select(.x, -col_one))
#> [[1]]
#> # A tibble: 5 x 3
#>   col_one col_two col_three
#>     <dbl>   <dbl>     <dbl>
#> 1   0.190   0.599     0.824
#> 2   0.214   0.172     0.106
#> 3   0.236   0.666     0.584
#> 4   0.373   0.903     0.252
#> 5   0.875   0.196     0.643
#> 
#> [[2]]
#> # A tibble: 5 x 2
#>   col_two col_three
#>     <dbl>     <dbl>
#> 1   0.513     0.113
#> 2   0.893     0.377
#> 3   0.275     0.675
#> 4   0.529     0.612
#> 5   0.745     0.405
#> 
#> [[3]]
#> # A tibble: 5 x 2
#>   col_two col_three
#>     <dbl>     <dbl>
#> 1   0.470     0.789
#> 2   0.181     0.289
#> 3   0.680     0.213
#> 4   0.772     0.114
#> 5   0.314     0.895

reprex package (v0.3.0)

于 2021-08-27 创建

我们可以对一个位置使用 modify_in,但是提供诸如 c(2,3) 的向量意味着我们想要访问嵌套列表中第二个父元素的第三个元素。这就是我们看到以下错误的原因。

# works
modify_in(tib_list, 2, ~ select(.x, -col_one))

#> [[1]]
#> # A tibble: 5 x 3
#>   col_one col_two col_three
#>     <dbl>   <dbl>     <dbl>
#> 1   0.109  0.697     0.0343
#> 2   0.304  0.645     0.851 
#> 3   0.530  0.786     0.600 
#> 4   0.708  0.0324    0.605 
#> 5   0.898  0.232     0.567 
#> 
#> [[2]]
#> # A tibble: 5 x 2
#>   col_two col_three
#>     <dbl>     <dbl>
#> 1  0.766     0.157 
#> 2  0.0569    0.0422
#> 3  0.943     0.0850
#> 4  0.947     0.0806
#> 5  0.761     0.297 
#> 
#> [[3]]
#> # A tibble: 5 x 3
#>   col_one col_two col_three
#>     <dbl>   <dbl>     <dbl>
#> 1   0.878   0.864     0.540
#> 2   0.168   0.745     0.120
#> 3   0.943   0.338     0.535
#> 4   0.353   0.478     0.204
#> 5   0.267   0.669     0.478

# doesn't work
modify_in(tib_list, c(2,3), ~ select(.x, -col_one))

#> Error in UseMethod("select"): no applicable method for 'select' applied to an object of class "c('double', 'numeric')"

我们可以使用modify_if

modify_if(tib_list,.f =  ~ .x %>% select(-col_one), 
       .p = seq_along(tib_list) != 1)

-输出

[[1]]
# A tibble: 5 x 3
  col_one col_two col_three
    <dbl>   <dbl>     <dbl>
1   0.819   0.666    0.384 
2   0.183   0.549    0.0211
3   0.374   0.240    0.252 
4   0.359   0.913    0.792 
5   0.515   0.402    0.217 

[[2]]
# A tibble: 5 x 2
  col_two col_three
    <dbl>     <dbl>
1   0.696    0.0269
2   0.433    0.147 
3   0.235    0.743 
4   0.589    0.748 
5   0.635    0.851 

[[3]]
# A tibble: 5 x 2
  col_two col_three
    <dbl>     <dbl>
1  0.707      0.976
2  0.0966     0.130
3  0.574      0.572
4  0.854      0.680
5  0.819      0.582