Question: I have a dataset looking like that:

```
set.seed(123)

test_data <- data.frame(
    id = c("a", "b", "c", "d", "e"),
    x = sample(c(0,1), 5, replace = T),
    y = sample(c(0,1), 5, replace = T)
)

> test_data
  id x y
1  a 0 1
2  b 0 1
3  c 0 1
4  d 1 0
5  e 0 0

```

For the columns x and y, if the value is equal to 1, the value is replaced by the name of the column. In my example, I would like to have:

```
  id    x    y
1  a <NA>    y
2  b <NA>    y
3  c <NA>    y
4  d    x <NA>
5  e <NA> <NA>

```

The thing that I don't know how many columns should be treated this way. Basically, I know that the first column ("id") is not concerned, but after this column, I could have any number of columns (even 0) that need to be treated this way.

I tried something like that but it doesn't work:

```
library(dplyr)

test_data %>% 
    mutate(
        across(
            .cols = 1:last_col(),
            .funs = function(x) {
                ifelse(x == 1, as.character(x), NA)
            }
        )
    )

```

How can I do that? A `dplyr` answer is preferred.

Answer: 
You can do this way also:

```
library(tidyverse)
## define a function for your job
fn <- function(x, name){
  return(ifelse(x ==1, name, NA))
}

test_data %>% 
  select(-id) %>% 
  map2_dfr(., names(.), ~fn(.x, .y)) %>% 
  bind_cols('id'= test_data$id, .)

```

Another version could be:

```
fn <- function(x, name){
      if(name != 'id'){
        return(ifelse(x ==1, name, NA))
       } else {
        return(x)
      }
}
test_data %>% 
  map2_dfr(., names(.), ~fn(.x, .y)) 

```
Here is a try using `purrr`

```
library(dplyr)
library(purrr)

col_to_fix <- names(test_data)[2:length(test_data)]
walk(.x = col_to_fix, .f = function(x) {
  # Note that I used <<- assigment here to change the test_data in global
  test_data[[x]] <<- case_when(
    test_data[[x]] == 1 ~ x,
    TRUE ~ NA_character_
  )
})

```

Output

```
> test_data

  id    x    y
1  a <NA>    y
2  b <NA>    y
3  c <NA>    y
4  d    x <NA>
5  e <NA> <NA>

```