1
votes

I ran across an excellent SO post/answer here, which demonstrates that original variables can be retained with dplyr::mutate_at while new variables are created with user-defined suffixes. The code runs as follows:

library(tidyverse)
dataframe <- data_frame(
  helloo = c(1, 2, 3, 4, 5, 6),
  ooooHH = c(1, 1, 1, 2, 2, 2),
  ahaaa = c(200, 400, 120, 300, 100, 100)
)

dataframe %>%
  mutate_at(
    vars(contains("oo")),
    .funs = funs(cat = ntile(., 2))
  )

which produces

# A tibble: 3 x 5
  helloo ooooHH ahaaa helloo_cat ooooHH_cat
   <dbl>  <dbl> <dbl>      <int>      <int>
1      1      1   200          1          1
2      2      1   400          1          1
3      3      1   120          2          2

However, it seems to be the case that if there is only one variable for vars, this suffix scheme does not work as above: for example:

varlist <- c('ooooHH')
dataframe %>% 
  mutate_at(
    vars(varlist), 
    .funs = funs(cat = ntile(., 2))
  )

produces output as

# A tibble: 3 x 4
  helloo ooooHH ahaaa   cat
   <dbl>  <dbl> <dbl> <int>
1      1      1   200     1
2      2      1   400     1
3      3      1   120     2

I understand the rational---there is no need to distinguish the new variables if only one variable is mutated. However, I desire to have cat column named as ooooHH_cat for consistency, because I will do this multiple times and the dynamic column names that go into vars will vary in length. In addition, I wish to preserve the result for when

varlist <- c('helloo', 'ooooHH')

Any suggestions?

1

1 Answers

1
votes

EDIT

Since , the strings are there in a variable, we cannot hardcode it.

varlist <- c('helloo', 'ooooHH')

we can modify the function to rename varlist object instead.

dataframe %>% 
  mutate_at(
  vars(varlist), 
   .funs = funs(cat = ntile(., 2))
 ) %>%
rename_at(vars(grep("^cat$", names(.))), 
          funs(sub("cat", paste0(varlist, "_cat"), .))) 

Original Answer

A hackish way from the same link would be using rename_at to replace only when we find an exact match for "cat"

library(dplyr)
dataframe %>% 
  mutate_at(
    vars('ooooHH'), 
    .funs = funs(cat = ntile(., 2))
   ) %>%
rename_at(vars(grep("^cat$", names(.))), funs(sub("cat", "ooooHH_cat", .))) 

#   helloo ooooHH ahaaa ooooHH_cat
#   <dbl>  <dbl> <dbl>      <int>
#1   1.00   1.00   200          1
#2   2.00   1.00   400          1
#3   3.00   1.00   120          1
#4   4.00   2.00   300          2
#5   5.00   2.00   100          2
#6   6.00   2.00   100          2

It would not impact when there are more than one column and the renaming is already applied.

dataframe %>%
   mutate_at(
   vars(contains("oo")),
    .funs = funs(cat = ntile(., 2))
  ) %>%
 rename_at(vars(grep("^cat$", names(.))), funs(sub("cat", "ooh_cat", .))) 


#   helloo ooooHH ahaaa helloo_cat ooooHH_cat
#   <dbl>  <dbl> <dbl>      <int>      <int>
#1   1.00   1.00   200          1          1
#2   2.00   1.00   400          1          1
#3   3.00   1.00   120          1          1
#4   4.00   2.00   300          2          2
#5   5.00   2.00   100          2          2
#6   6.00   2.00   100          2          2