Giora Simchoni
Giora Simchoni

Reputation: 3689

Getting the name of a column as an additional argument to function in a mutate_all tidy pipe

I want to use a column's name inside a function, without explicitly giving it as an argument to that function, called in a tidy (dplyr, tidyr, purrr, ...) pipe. This is because I would want to use this function on many columns (e.g. with mutate_all and map), not mutateing each column separately.

Example:

Let's say I'd like each value in each column to be prefixed by that column name and an underscore. The following works:

library(dplyr)
library(purrr)
library(stringr)

tib <- tibble(a = 1:3, b = 4:6, c = 7:9)

f <- function(value, column_name) {
  str_c(column_name, "_", value)
}

tib %>%
  mutate(a = map_chr(a, f, "a"),
         b = map_chr(b, f, "b"),
         c = map_chr(c, f, "c"))

# A tibble: 3 x 3
  a     b     c
<chr> <chr> <chr>
1   a_1   b_4   c_7
2   a_2   b_5   c_8
3   a_3   b_6   c_9

But what if I have n >> 3 columns?

It would be nice to have a function which finds out the column name by itself, then I can use mutate_all:

f2 <- function(value) {
  column_name <- miraculously_get_column_name()
  str_c(column_name, "_", value)
}

tib %>%
  mutate_all(f2)

But that's no going to happen. A probably more realistic wish is to enter as an additional argument to mutate_all an expression which finds the column name to each column and use the original f, something like:

tib %>%
  mutate_all(f, get_column_name_somehow())

So how do I do this with a pipe (and if there's another way and no way of doing this with a tidy pipe, let's have it then).

Upvotes: 1

Views: 232

Answers (1)

moodymudskipper
moodymudskipper

Reputation: 47340

You can do it this way:

tib %>% map2_df(names(.),f)

Or as @aosmith mentions in the comments you can use imap_dfc which is the precise answer to your question:

tib %>% imap_dfc(f)

Upvotes: 4

Related Questions