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

mapnm_* #240

Closed
hadley opened this Issue Sep 7, 2016 · 12 comments

Comments

Projects
None yet
3 participants
@hadley
Member

hadley commented Sep 7, 2016

Would be useful to have

mapn <- function(.x, .f, ...) {
  out <- map2(names(.x), .x, .f, ...)
  names(out) <- names(.x)
  out
}

For more complicated stuff it is better off to using a tribble + list-cols etc, but this is still a very useful pattern.

@hadley hadley changed the title from mapn_* to mapnm_* Sep 7, 2016

@lionel-

This comment has been minimized.

Member

lionel- commented Sep 7, 2016

+1, I use this all the time. Never been able to find a satisfying name though. I've been thinking about something like tagged_map(), or map2_nx() to reflect the contents of the arguments. But map2_nx_int() etc don't look great.

To be consistent with pmap() should it be a prefix, eg nmap()?

@hadley

This comment has been minimized.

Member

hadley commented Sep 7, 2016

Yeah, nmap might be best

@jennybc

This comment has been minimized.

Member

jennybc commented Sep 7, 2016

It feels like map2(seq_along(.x), .x, .f, ...) also comes up.

@hadley

This comment has been minimized.

Member

hadley commented Sep 7, 2016

Maybe imap for that?

@lionel-

This comment has been minimized.

Member

lionel- commented Sep 7, 2016

Should we generalise the pattern?

x %>% map_with(names, f)

x %>% map_lgl_with(seq_along, f)
@hadley

This comment has been minimized.

Member

hadley commented Sep 7, 2016

Maaaaaybe, but the goal is to be shorter than map2(), so I think names() would have to be the default, which means that the argument would need to come later and usually be supplied by a named argument.

@lionel-

This comment has been minimized.

Member

lionel- commented Sep 7, 2016

hmm you're right, map_with() would be unnecessary jargon.

Perhaps we can combine the names and index mappers into one function, and have the seq_along() when the input is unnamed.

x %>% imap(f)
unname(x) %>% imap(f)
@hadley

This comment has been minimized.

Member

hadley commented Sep 7, 2016

Oh yeah, that makes sense

@lionel-

This comment has been minimized.

Member

lionel- commented Sep 7, 2016

For tilde-lambda's it'd be weird to have the index/names as .x and the input as .y. It would be nicer to have .x and .i.

@jennybc

This comment has been minimized.

Member

jennybc commented Sep 7, 2016

Perhaps we can combine the names and index mappers into one function, and have the seq_along() when the input is unnamed.

That has the really nice property that it's what you would get if you used tibble::enframe() and took the list-cols approach @hadley alluded to at the very start.

@hadley

This comment has been minimized.

Member

hadley commented Jan 26, 2017

I propose we call this family of functions imap_*, and define it something like this:

index <- function(x) {
  names(x) %||% seq_along(x)
}

imap <- function(.x, .f, ...) {
  f <- as_function(.f, ..., .arg_names = c(".x", ".i"))
  map2(.x, index(.x), .f, ...)
}

(assuming some changes to as_function())

I think it's more logical to pass the index as the second argument, which also naturally leads to preserving the names/indices of the first.

@hadley hadley added the feature label Mar 3, 2017

@hadley hadley closed this in a37ea61 Mar 5, 2017

@hadley

This comment has been minimized.

Member

hadley commented Mar 5, 2017

Decided to not customise the argument names; introducing another variant seems confusing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment