Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the correct way of using `keep` function in `purrr` package

Tags:

r

purrr

Suppose I have a list x as below:

library(purrr)

set.seed(4152)
x <- rerun(5, a = sample(c("A","B","C","D"),1), b = c(1,2,3,4,5))

x

[[1]]
[[1]]$a
[1] "B"

[[1]]$b
[1] 1 2 3 4 5


[[2]]
[[2]]$a
[1] "B"

[[2]]$b
[1] 1 2 3 4 5


[[3]]
[[3]]$a
[1] "C"

[[3]]$b
[1] 1 2 3 4 5


[[4]]
[[4]]$a
[1] "C"

[[4]]$b
[1] 1 2 3 4 5


[[5]]
[[5]]$a
[1] "A"

[[5]]$b
[1] 1 2 3 4 5

I would like to keep all elements in the list x that $a %in% c("A","C"), so I tried:

x_sub <- x %>%
         keep(., "a" %in% c("A","C"))

Error: length(.p) == length(.x) is not TRUE

I think it is a nature way of coding based on my understanding of keep function. Why does it report error? Any suggestions are appreciated.

like image 901
Chuan Avatar asked Oct 29 '25 19:10

Chuan


1 Answers

You have the right idea but need to leverage as_mapper() to create a predicate function that will access the value that you want within the list. Instead of saying "a" in c("A", "C") we will say x$a in c("A","C") small difference but that makes it work.

library(tidyverse)

set.seed(4152)
x <- rerun(5, a = sample(c("A","B","C","D"),1), b = c(1,2,3,4,5))

x_sub <- x %>%
  keep(., as_mapper(~.x$a %in% c("A","C")))

x_sub
#> [[1]]
#> [[1]]$a
#> [1] "C"
#> 
#> [[1]]$b
#> [1] 1 2 3 4 5
#> 
#> 
#> [[2]]
#> [[2]]$a
#> [1] "C"
#> 
#> [[2]]$b
#> [1] 1 2 3 4 5
#> 
#> 
#> [[3]]
#> [[3]]$a
#> [1] "A"
#> 
#> [[3]]$b
#> [1] 1 2 3 4 5

Created on 2019-05-01 by the reprex package (v0.2.1)

like image 67
dylanjm Avatar answered Oct 31 '25 10:10

dylanjm



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!