1
votes

i'm working with dplyr, and i have a tibble like this:

df<- data_frame(one= c(1, NA, 1),
       two= c(NA,NA,1),
       three= c(1, 1,1)
       )
----------------------------
# A tibble: 3 x 3
      one   two  three
     <dbl> <dbl> <dbl>
 1     1    NA     1
 2    NA    NA     1
 3     1     1     1
----------------------------

i need to obtain something like this:

----------------------------
# A tibble: 3 x 3
      one    two    three
     <dbl>  <dbl>   <dbl>
 1    one    NA     three
 2    NA     NA     three
 3    one    two    three
----------------------------

So i can use ifelse function with mutate for each column:

df %>%
      one= ifelse(!is.na(one),'one', NA ),
      two= ifelse(!is.na(two),'two', NA ),
      three= ifelse(!is.na(three),'three', NA ),

But in my real df i have many columns, then this wat is very inefficient. i need something more elegant, using mutate_at and the column name but it's seem very hard. I tried to do that in many ways but everytime i get an error. Any advice?

1

1 Answers

1
votes

If there is only 1's and NAs in the dataset, multiply the col(df) with the dataset, unlist and based on the index, just replace it with names of the dataset and assign it back to the original data

df[] <- names(df)[unlist(col(df)*df)]
df
# A tibble: 3 x 3
#    one   two three
#  <chr> <chr> <chr>
#1   one  <NA> three
#2  <NA>  <NA> three
#3   one   two three

Or with tidyverse, we can do this for each column (map2_df from purrr)

library(tidyverse)
df %>%
     map2_df(names(.), ~replace(., !is.na(.), .y))
# A tibble: 3 x 3
#    one   two three
#  <chr> <chr> <chr>
#1   one  <NA> three
#2  <NA>  <NA> three
#3   one   two three