Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring back rerun(), or adjust map()? #1125

Closed
lmiratrix opened this issue Apr 23, 2024 · 6 comments
Closed

Bring back rerun(), or adjust map()? #1125

lmiratrix opened this issue Apr 23, 2024 · 6 comments
Labels
reprex needs a minimal reproducible example

Comments

@lmiratrix
Copy link

I run a lot of simulations, and relied heavily on rerun(). The current view is this should be replaced with map( 1:R, ~ one_run() ) rather than rerun( R, one_run() ). But this makes it hard to pass arguments through to one_run() since the map version makes the anonymous function take an extra ID number, which is often not particularly useful for the one_run() call.

E.g., consider passing through triple dots like this:

func = function( x, ... ) {
  cat( "func - x = ", x, "\n" )
  print( list( ... ) )
  
}

func_wrap <- function( r, ... ) {

  cat( "func_wrap:\n" )
  print( list( ... ) )
  
  func( 10, ... )
  
  res <- map( r:(r+1), ~ {
    cat( "** map tick\n" )
    func( x=4, ... ) } )
  
  invisible( res )
}


func_wrap( 4, a=2, b=3 )

This has ties to the behavior noted in #1118 (which I flagged before, but this keeps coming up for me--I am posting this as it seems a different take on the original issue)

@hadley
Copy link
Member

hadley commented Jul 15, 2024

Would you mind providing an example with rerun() and map() showing where map() is not as nice?

@hadley hadley added the reprex needs a minimal reproducible example label Jul 15, 2024
@lmiratrix
Copy link
Author

This is one snippit (the map version doesn't work).

one_run <- function( N = 10, sd = 1 ) {
    nn <- sort( rnorm( N, mean=0, sd=sd ) )
    nn[2] - nn[1]
}

sim_map <- function( reps, N=10, sd=1 ) {
    rs <- purrr::map_dbl( 1:reps, ~ one_run( N=N, sd=sd ) )
    tibble( avg = mean(rs),
            sd = sd( rs ) )
}

sim_rerun <- function( reps, ... ) {
    rs <- purrr::rerun( reps, one_run( ... ) ) %>%
        as.numeric()
    tibble( avg = mean(rs),
            sd = sd( rs ) )
}


sim( 100, N=100, sd=100 ) # fails
sim_rerun( 5, N=100, sd=100 )

Mainly, if you don't care about iteration number, having it as an argument to your inner function is hard. I.e., something akin to this would be nicer, I think:

    rs <- purrr::repeat( reps, one_run, N=N, sd=sd )

@hadley
Copy link
Member

hadley commented Jul 23, 2024

What's wrong with this?

library(purrr)

one_run <- function(N = 10, sd = 1) {
  nn <- sort(rnorm(N, mean = 0, sd = sd))
  nn[2] - nn[1]
}

sim_map <- function(reps, ...) {
  rs <- purrr::map_dbl(1:reps, \(i) one_run(...)) 
  tibble::tibble(avg = mean(rs), sd = sd(rs))
}

sim_map(5, N = 100, sd = 100)
#> # A tibble: 1 × 2
#>     avg    sd
#>   <dbl> <dbl>
#> 1  44.9  32.4

Created on 2024-07-23 with reprex v2.1.0

@lmiratrix
Copy link
Author

For teaching there is some pedagogical weight to generating the list of numbers and then tossing them, rather than the old rerun which very clearly does it's one thing (and I run into this frequently, as this kind of coding gets very confusing to newbies very fast), but the (i) seems to mostly be fine, other than the cleanness of rerun, which I still miss.

@hadley
Copy link
Member

hadley commented Jul 25, 2024

I think the main problem with rerun() is illustrated by your sim_rerun() — you don't want just rerun(), but rerun_dbl(), rerun_lgl() etc. And to me, that feels like a lot of extra functions for relatively little additional functionality. And rerun() works differently to every other purrr function, because it takes an expression not a function. So overall, I don't think it's a good fit for purrr, but that doesn't mean it shouldn't live somewhere, so maybe this is your opportunity to create a package 😄

@hadley hadley closed this as completed Jul 25, 2024
@lmiratrix
Copy link
Author

lmiratrix commented Jul 25, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
reprex needs a minimal reproducible example
Projects
None yet
Development

No branches or pull requests

2 participants