简体   繁体   中英

How to swap (translate) values inside a vector

Let

vetA <- c(1,2,1,2,1,3,4,1,2,3,2,1,4)

What are the possibilities so I could do the following swap? Swap:

  • 1 --> 3
  • 2 --> 4
  • 3 --> 2
  • 4 --> 1

I have tried this:

vetB <- as.factor(vetA)
levels(vetB) <- c(3,4,2,1)
vetA <- as.integer(vetB)

# because
print(vetB)
# [1] 3 4 3 4 3 2 1 3 4 2 4 3 1
#Levels: 3 4 2 1

It didn't work. Could you please give me a hand?

If you converted your factor vector to character before converting it to integer, your code will work. Notice that factor is internally stored as integer, so as.integer(vetB) would return its integer levels.

vetA <- c(1,2,1,2,1,3,4,1,2,3,2,1,4)

vetB <- as.factor(vetA)
levels(vetB) <- c(3,4,2,1)
vetA <- as.integer(as.character(vetB))
vetA
# [1] 3 4 3 4 3 2 1 3 4 2 4 3 1

You can create a look-up table:

vetA <- c(1,2,1,2,1,3,4,1,2,3,2,1,4)
lookup <- setNames(c(3, 4, 2, 1), 1:4)
lookup[vetA]
## 1 2 1 2 1 3 4 1 2 3 2 1 4 
## 3 4 3 4 3 2 1 3 4 2 4 3 1

The values of lookup are the new values, while the names are set to the old values. You can then use your vector vetA as index to pick the new values.

Since the values that you replace are simply c(1, 2, 3, 4) , there is actually no need to set the names explicitly and you could get the same result simply with

c(3, 4, 2, 1)[vetA]
## [1] 3 4 3 4 3 2 1 3 4 2 4 3 1

However, the solution above will also work in situations where the values that you replace are not just an integer sequence.

One possible option would be to use match :

vetA <- c(1,2,1,2,1,3,4,1,2,3,2,1,4)
old=c(1,2,3,4)
new=c(3,4,2,1)
new[match(vetA,old)]

Output:

3 4 3 4 3 2 1 3 4 2 4 3 1

Hope this helps!

You could simply do

new[order(old)][vetA]

# [1] 3 4 3 4 3 2 1 3 4 2 4 3 1

where

vetA <- c(1,2,1,2,1,3,4,1,2,3,2,1,4)
old <- c(1,2,3,4)
new <- c(3,4,2,1)

Note: This would work—as well as the accepted answer by @Florian—even if the vector old is not sorted. The other two answers won't work in which case. For example if

old <- c(3,2,1,4)
new <- c(3,4,2,1)

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