2

When using for example a for loop I can use next to skip a certain item:

    if (i == 5) next
    print (i)

Is there a similar way to do this in a map() or more specifically in a pmap()?

a <- c(1,2,3)
b <- c(1,1,1)
c <- c(2,2,2)

mapped <- pmap(list(a,b,c),
               function(a,b,c){
                # if (a == 2) next
                print( a + b - c)
               })

Thank you for your help!

########## Edit for formatting of my follow up question to Konrad: Is there any way to avoid getting a NULL element in the list when using if (a != 2)?

a <- c(1,2,3)
b <- c(1,1,1)
c <- c(2,2,2)

mapped <- pmap(list(a,b,c),
               function(a,b,c){
                 if(a != 2){
                 a + b - c
                 }
               })

str(mapped)

returns

#List of 3
 #$ : num 0
 #$ : NULL
 #$ : num 2

But for my solution I would need

#List of 2
 #$ num 0
 #$ num 2
Jonas
  • 121,568
  • 97
  • 310
  • 388
rbeginner
  • 41
  • 3
  • It looks as if you're using `pmap` for its side effect (printing a+b-c) not for its return value. You probably want one of the `walk` family. Or why not use a for loop? – dash2 Feb 08 '22 at 10:41

2 Answers2

3

No, the design of map and pmap is that they apply the function to every element. If you want to skip one, then skip it on the input:

library(purrr)
a <- c(1,2,3)
b <- c(1,1,1)
c <- c(2,2,2)
keep <- a != 2

mapped <- pmap(list(a[keep], b[keep], c[keep]),
               function(a,b,c){
                 a + b - c
               })

str(mapped)
#> List of 2
#>  $ : num 0
#>  $ : num 2

Created on 2022-02-08 by the reprex package (v2.0.1.9000)

You can also use purrr functions to do the initial filtering, for example

list(a,b,c) %>% 
map(~ .[a != 2]) %>% 
pmap(function(a,b,c){
       a + b - c
     })
user2554330
  • 37,248
  • 4
  • 43
  • 90
0

You can't fully skip, but you can use a return() toward the top and save time running the unnecessary calculations.

Just return something that fits the type or structure of the other returned elements.

And filter out the missing elements in post-processing

library(tidyverse)
#> Warning: package 'tidyverse' was built under R version 4.1.3
#> Warning: package 'ggplot2' was built under R version 4.1.3
#> Warning: package 'tibble' was built under R version 4.1.3
#> Warning: package 'tidyr' was built under R version 4.1.3
#> Warning: package 'readr' was built under R version 4.1.3
#> Warning: package 'dplyr' was built under R version 4.1.3

a <- c(1,2,3)
b <- c(1,1,1)
c <- c(2,2,2)

mapped <- pmap(list(a,b,c),
               function(a,b,c){
                 if(a == 2) return(NULL)
                 a + b - c
               })

str(Filter(Negate(is.null), mapped))
#> List of 2
#>  $ : num 0
#>  $ : num 2
str(mapped[!map_lgl(mapped, is.null)])
#> List of 2
#>  $ : num 0
#>  $ : num 2

Created on 2023-02-25 by the reprex package (v2.0.1)

D Bolta
  • 423
  • 3
  • 8