Is There an Alternative to "Revalue" Function from Plyr When Using Dplyr

Is there an alternative to revalue function from plyr when using dplyr?

There is a recode function available starting with dplyr version dplyr_0.5.0 which looks very similar to revalue from plyr.

Example built from the recode documentation Examples section:

set.seed(16)
x = sample(c("a", "b", "c"), 10, replace = TRUE)
x
[1] "a" "b" "a" "b" "b" "a" "c" "c" "c" "a"

recode(x, a = "Apple", b = "Bear", c = "Car")

[1] "Car" "Apple" "Bear" "Apple" "Car" "Apple" "Apple" "Car" "Car" "Apple"

If you only define some of the values that you want to recode, by default the rest are filled with NA.

recode(x, a = "Apple", c = "Car")
[1] "Car" "Apple" NA "Apple" "Car" "Apple" "Apple" "Car" "Car" "Apple"

This behavior can be changed using the .default argument.

recode(x, a = "Apple", c = "Car", .default = x)
[1] "Car" "Apple" "b" "Apple" "Car" "Apple" "Apple" "Car" "Car" "Apple"

There is also a .missing argument if you want to replace missing values with something else.

Use revalue in data manipulation with dplyr

The problem is that variable1 is not a factor or character vector. It's the "name" of a column in a data frame. The revalue function expects factors or character vectors. You can eliminate the problem by using the mutate() function like this:

# your code    
data <- data.frame(variable1 = as.factor(rep(c("A","B","C"), each=5)),
variable2 = rnorm(15,10,2))

require(plyr)
require(dplyr)

# corrected code
data <-
data %>%
mutate(variable1 = revalue(variable1, c("A"="House", "B"="Flat", "C"="Loft")))

R creating a function using plyr revalue with multiple inputs

As already mentioned by @MartinGal in his comment, plyr is retired and the package authors themselves recommend using dplyr instead. See https://github.com/hadley/plyr.

Hence, one option to achieve your desired result would be to make use of dplyr::recode. Additionally if you want to write your function I would suggest to pass the values to recode and the replacements as vectors instead of passing each value and replacement as separate arguments:

library(dplyr)

set.seed(42)

df <- data.frame(
Area = sample(c("rural", "suburban", "urban"), 10, replace = TRUE)
)

recode_table <- c("rural" = 1, "suburban" = 2, "urban" = 3)

recode(df$Area, !!!recode_table)
#> [1] 1 1 1 1 2 2 2 1 3 3

reval_3 <- function(data, x, values, replacements) {
recode_table <- setNames(replacements, values)
data[[x]] <- recode(data[[x]], !!!recode_table)
data
}

df <- reval_3(df, "Area", c("rural", "suburban", "urban"), 1:3)
df
#> Area
#> 1 1
#> 2 1
#> 3 1
#> 4 1
#> 5 2
#> 6 2
#> 7 2
#> 8 1
#> 9 3
#> 10 3

Revalue in R with a default

Here's an alternative

> sites <- gsub("\\.com$", "", sites)
> ifelse(sites %in% c("facebook", "google"), sites, "other")
[1] "other" "other" "facebook" "google" "other"


Related Topics



Leave a reply



Submit