Tyler Smith
Tyler Smith

Reputation: 328

dplyr::recode_factor with a priori unknown levels

I'm looking for a method to apply dplyr's recode_factor when the level that I am wanting to modify is not known beforehand. For example, I would like to apply cut(5) to a column and adjust the first level (interval) to start at 0.

set.seed(42)

library(dplyr)
library(stringr)

x <- rgamma(100, 1)
x_cut <- x %>% cut(5)
old_level <- levels(x_cut)[[1]]
new_level <- old_level %>% str_extract_all("[0-9]+\\.([0-9]+)",simplify=TRUE) %>% `[`(2) %>% paste0("(0,",.,"]")
x_cut %>% recode_factor( old_level = new_level) %>% levels

but this doesn't seem to work.

I expect to see

[1] "(0,1.38]" "(1.38,2.75]"    "(2.75,4.12]"    "(4.12,5.49]"    "(5.49,6.87]"

but nothing is changed and I get

[1] "(0.00388,1.38]" "(1.38,2.75]"    "(2.75,4.12]"    "(4.12,5.49]"    "(5.49,6.87]"

Upvotes: 1

Views: 242

Answers (1)

andrew_reece
andrew_reece

Reputation: 21264

The left hand side of your recode pair old_level = new_level needs to be evaluated instead of quoted.

Use the !! and := syntax to do this:

x_cut %>% recode_factor(!!old_level := new_level) %>% levels

For example, with set.seed(42):

x_cut
#  "(0.00388,1.38]" "(1.38,2.75]" "(2.75,4.12]" "(4.12,5.49]" "(5.49,6.87]"   
old_level
#  "(0.00388,1.38]"
new_level
#  "(0,1.38]"
x_cut %>% recode_factor(!!old_level := new_level) %>% levels
#  "(0,1.38]" "(1.38,2.75]" "(2.75,4.12]" "(4.12,5.49]" "(5.49,6.87]"

See the dplyr programming docs for more on !! ("bang bang") notation.

Upvotes: 1

Related Questions