I have a data frame that looks like this
set.seed(123)
test_data <- data.frame(id = 1:6,
var1 = rbinom(n = 6, size = 1, prob = .5),
var2 = rbinom(n = 6, size = 1, prob = .5),
age = sample(18:30, size = 6, replace = T))
I want to use dplyr or purrr to change the values that are equal to 1 in var1 and var2, to the name of their column and keep the 0's the way they are.
The result would look like this.
id var1 var2 age
1 0 var2 26
2 var1 var2 25
3 0 var2 19
4 var1 0 29
5 var1 var2 21
6 0 0 18
I have tried using dplyr::mutate_at
mutate_at(test_data,
vars(var1, var2),
function(var_x) { ifelse(var_x == 1, colnames(var_x), var_x) })
This returns the following error. So, probably not the best way to go.
Error in evalq(sys.calls(), ) : replacement has length zero In addition: Warning message: In rep(yes, length.out = length(ans)) : 'x' is NULL so the result will be NULL
And I have tried using purrr:map_at
map_at(test_data,
c("var1", "var2"),
function(var_x) { ifelse(var_x == 1, colnames(var_x), var_x) })
And this returns this error.
Error in ans[test & ok] <- rep(yes, length.out = length(ans))[test & ok] : replacement has length zero In addition: Warning message: In rep(yes, length.out = length(ans)) : 'x' is NULL so the result will be NULL
While I'd prefer to work with dplyr or purrr, I'm open to suggestions using other approaches.
Here is an idea via tidyverse. The trick here is to gather first, replace the values and then spread
library(tidyverse)
test_data %>%
gather(var, val, -c(id, age)) %>%
mutate(val = ifelse(val == 1, var, val)) %>%
spread(var, val)
# id age var1 var2
#1 1 26 0 var2
#2 2 25 var1 var2
#3 3 19 0 var2
#4 4 29 var1 0
#5 5 21 var1 var2
#6 6 18 0 0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With