Replace multiple value of a vector with the condition of another vector

Viewed 88

I have vectors Xval and index as follows

Xval <- c(-10, 5, 25, 10, 5, 21, 48, 4, 57, 14, 10, 15)
index <- c(1, 2, 2, 1, 3, 1, 3, 3, 1, 2, 1, 1)

I would like to replace index value conditioning on Xval_mean

Xval_mean <- tapply(Xval, index, mean)
# 1        2        3 
# 17.16667 14.66667 19.00000

Replace the index value by 1 for which Xval_mean is maximum, by 2 for which Xval_mean is minimum, and by 3 for the middle value of Xval_mean. I can do it for max and min separately as

index[index == which.max(Xval_mean)] <- 1
index[index == which.min(Xval_mean)] <- 2

and for middle value of Xval_mean, index should be 3. I need to do them together. Any help is appreciated

3 Answers

You can try :

val <- names(c(which.max(Xval_mean), which.min(Xval_mean)))
val <- c(val, setdiff(names(Xval_mean), val))
index <- match(index, val)
index
#[1] 3 2 2 3 1 3 1 1 3 2 3 3

An easy way is to order the names of aggregate Xval_mean and match them with index.

index2 <- match(index, names(Xval_mean[order(-Xval_mean)]))

Check:

cbind(Xval, index, index2)[order(index), ]
#       Xval index index2
#  [1,]  -10     1      2
#  [2,]   10     1      2
#  [3,]   21     1      2
#  [4,]   57     1      2
#  [5,]   10     1      2
#  [6,]   15     1      2
#  [7,]    5     2      3
#  [8,]   25     2      3
#  [9,]   14     2      3
# [10,]    5     3      1
# [11,]   48     3      1
# [12,]    4     3      1

Maybe you can used named vector like below

> nm <- setNames(c(1, 3, 2), names(sort(Xval_mean, decreasing = TRUE)))

> nm[as.character(index)]
1 2 2 1 3 1 3 3 1 2 1 1
3 2 2 3 1 3 1 1 3 2 3 3
Related