user7777508
user7777508

Reputation: 101

Recoding multiple variables in R

I would like to recode multiple variables at once in R. The variables are within a larger dataframe. Here is some example data:

 z <- data.frame (A = c(1,2,300,444,555),
              B = c(555,444,300,2,1),
              C = c(1,2,300,444,555),
              D = c(1,2,300,444,555))

What I would like to do is recode all values that equal 300 as 3, 444 as 4, and 555 as 5.

I thought I could possibly do this in a list. Here is what I tried:

example_list  = list(c("A", "B", "C", "D"))

example_list <- apply(z[,example_list], 1, function(x) ifelse(any(x==555, na.rm=F), 0.5,
                                                              ifelse(any(x==444), 0.25),
                                                              ifelse(any(x==300), 3, example_list)))

I get this error:

Error during wrapup: invalid subscript type 'list'

Then tried using "lapply" and I got this error:

Error during wrapup: '1' is not a function, character or symbol

Even then I'm not sure this is the best way to go about doing this... I would just like to avoid doing this line by line for multiple variables. Any suggestions would be amazing, as I'm new to R and don't entirely understand what I'm doing wrong.

I did find a similar questions on SO: Question, but I'm not sure how to apply that to my specific problem.

Upvotes: 4

Views: 2658

Answers (6)

Hellen Geremias
Hellen Geremias

Reputation: 43

If you alredy have factor variables and also want factor variables as result you can use the following code:

library(tidyverse)
z <- data.frame (A = factor(c(1,2,300,444,555)),
                 B = factor(c(555,444,300,2,1)),
                 C = factor(c(1,2,300,444,555)),
                 D = factor(c(1,2,300,444,555)))

new.z <- z %>% 
mutate_all(function(x) recode_factor(x, "300" = "3", "444" = "4", "555" = "5"))

Upvotes: 0

thelatemail
thelatemail

Reputation: 93938

Here's a base R attempt which should be neatly extendable and pretty fast:

# set find and replace vectors
f <- c(300,444,555)
r <- c(3, 4, 5)
# replace!
m   <- lapply(z, function(x) r[match(x,f)] )
z[] <- Map(function(z,m) replace(m,is.na(m),z[is.na(m)]), z, m)

#  A B C D
#1 1 5 1 1
#2 2 4 2 2
#3 3 3 3 3
#4 4 2 4 4
#5 5 1 5 5

Upvotes: 2

Gregory Demin
Gregory Demin

Reputation: 4846

z =  data.frame (A = c(1,2,300,444,555),
                 B = c(555,444,300,2,1),
                 C = c(1,2,300,444,555),
                 D = c(1,2,300,444,555))



library(expss)

to_recode = c("A", "B", "C", "D")
recode(z[, to_recode]) = c(300 ~ 3, 444 ~ 4, 555 ~ 5)

Upvotes: 0

Sraffa
Sraffa

Reputation: 1668

Using case_when:

library(dplyr)
z %>% mutate_all(
    function(x) case_when(
        x == 300 ~ 3,
        x == 444 ~ 4,
        x == 555 ~ 5,
        TRUE ~ x
    )
)

  A B C D
1 1 5 1 1
2 2 4 2 2
3 3 3 3 3
4 4 2 4 4
5 5 1 5 5

Upvotes: 2

Yannis Vassiliadis
Yannis Vassiliadis

Reputation: 1709

This should work.

library(plyr) 
new.z<- apply(z, 1, function(x) mapvalues(x, from = c(300, 444, 555), to = c(3, 4, 5)))

Upvotes: 1

RoyalTS
RoyalTS

Reputation: 10203

This seems a bit clunky but it works:

mutate_cols <- c('A', 'B')

z[, mutate_cols] <- as.data.frame(lapply(z[, mutate_cols], function(x) ifelse(x == 300, 3, 
                                                                              ifelse(x == 444, 4, 
                                                                                     ifelse(x== 555, 5, x)))))

Upvotes: 1

Related Questions