Reputation: 997
Lets say, I have a vector
animal <- c('cat','snake','cat','pigeon','snake')
And a dataframe called
map <- data.frame(find=c('cat','snake','pigeon'),replace=c('mammal','reptile','bird')
Now I want animal to be modified using the map by matching each element of animal to the replace column of map. So I am expecting:
animal <- c('mammal','reptile','mammal','bird','reptile')
How can I do this without using loops over each element of my first vector?
Upvotes: 1
Views: 6351
Reputation: 9624
You can treat animal
as a factor and rename its levels.
For example, using the plyr
package:
library(plyr)
animal <- c('cat','snake','cat','pigeon','snake')
animal2 <- revalue(animal, c("cat" = "mammal",
"snake" = "reptile",
"pigeon" = "bird"))
> animal
[1] "cat" "snake" "cat" "pigeon" "snake"
> animal2
[1] "mammal" "reptile" "mammal" "bird" "reptile"
To make it automatic as required in the comment below
repl <- as.character(map$replace)
names(repl) <- map$find
animal2 <- revalue(animal, repl)
> animal
[1] "cat" "snake" "cat" "pigeon" "snake"
> animal2
[1] "mammal" "reptile" "mammal" "bird" "reptile"
Upvotes: 2
Reputation: 185
You can use the match
function:
> animal <- as.character(map[match(animal, map$find), "replace"])
> animal
[1] "mammal" "reptile" "mammal" "bird" "reptile"
Upvotes: 3
Reputation: 7474
For this purpose I use simple recode
function. As input you need vector to be changed denoted as x
, vector of values to be changes from
and a vector of replacement values to
(so from[1]
is recoded to to[1]
), you can specify other
value and all the values that are not in from
will be recoded to other
. You can find the function pasted below.
recode <- function(x, from, to, other) {
stopifnot(length(from) == length(to))
new_x <- x
k <- length(from)
for (i in 1:k) new_x[x == from[i]] <- to[i]
if (!missing(other) && length(other) > 1) {
new_x[!(x %in% from)] <- other[1]
warning("'other' has length > 1 and only the first element will be used")
}
new_x
}
using your own example the usage would be
recode(animal, map$find, map$replace)
Upvotes: 1