简体   繁体   中英

How can we replace elements in a vector in R?

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?

You can use the match function:

> animal <- as.character(map[match(animal, map$find), "replace"])
> animal
[1] "mammal"  "reptile" "mammal"  "bird"    "reptile"

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"

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM