Chris
Chris

Reputation: 2071

missing argument when using lapply in R

I have the following dataframe:

set.seed(1)
df <- data.frame(X1 = sample(c(letters[1:5],NA),10,replace=TRUE),
                X2 = sample(c(letters[1:5],NA),10,replace=TRUE),
                X3 = sample(c(letters[1:5],NA),10,replace=TRUE),
                stringsAsFactors = FALSE)
     X1   X2   X3
1     b    b <NA>
2     c    b    b
3     d    e    d
4  <NA>    c    a
5     b    e    b
6  <NA>    c    c
7  <NA>    e    a
8     d <NA>    c
9     d    c <NA>
10    a    e    c

I want to replace a for 5, b for 4, c for 3, d for 2, and e for 1, with:

df %>% lapply(., plyr::mapvalues(, c("a","b","c","d","e"), c(5,4,3,2,1)))

But it doesn't work: I get a warning that it's missing the first argument of the function mapvalues(). Does anyone know what I am doing wrong?

Upvotes: 1

Views: 426

Answers (2)

Cettt
Cettt

Reputation: 11981

The syntax using lapply is slightly different. Here is how it works:

df %>% lapply(plyr::mapvalues, from = c("a","b","c","d","e"), to = c(5,4,3,2,1))
    $X1
 [1] "1" "3" "3" "1" "1" "2" "4" "5" NA  "2"

$X2
 [1] "2" "1" NA  "3" "1" "5" "3" "2" NA  NA 

$X3
 [1] "3" "3" NA  "1" NA  "1" "1" "2" NA  "2"

If you still want to have a dataframe afterwards it is better to use apply instead of lapply:

df %>% apply(2, plyr::mapvalues, from = c("a","b","c","d","e"), to = c(5,4,3,2,1)) %>% 
  as.data.frame(stringsAsFactors = F)
     X1   X2   X3
1     4    4 <NA>
2     3    4    4
3     2    1    2
4  <NA>    3    5
5     4    1    4
6  <NA>    3    3
7  <NA>    1    5
8     2 <NA>    3
9     2    3 <NA>
10    5    1    3

Upvotes: 1

coffeinjunky
coffeinjunky

Reputation: 11514

A simple yet straightforward approach:

lookup <- 5:1
names(lookup) <- c("a","b","c","d","e")

df[] <- lapply(df, function(x) lookup[x])
df
   X1 X2 X3
1   4  4 NA
2   3  4  4
3   2  1  2
4  NA  3  5
5   4  1  4
6  NA  3  3
7  NA  1  5
8   2 NA  3
9   2  3 NA
10  5  1  3

Note that lookup is a simple named vector, i.e.

> lookup
a b c d e 
5 4 3 2 1 

And df[] ensures that you keep the dataframe structure when you lapply over it. Within the call to lapply, the values in each column are simply used for a lookup by name in the lookup table. To highlight this, lookup["c"] returns the value "3".

Upvotes: 1

Related Questions