Search code examples
rsortingvectorlogical-operatorsrelational-operators

Named Numeric Vector (in ascending order) to Named Logical Vector based on condition


I have a named numeric vector vec, then it was sorted in ascending order and saved in object vec_sort, as shown below.

vec <- c(1,1,1,2,3,1,5)
names(vec) <- letters[1:7]
vec
# a b c d e f g 
# 1 1 1 2 3 1 5 

str(vec)
# Named num [1:7] 1 1 1 2 3 1 5
# - attr(*, "names")= chr [1:7] "a" "b" "c" "d" ...

Sorted in Ascending Order (Named Numeric Vector)

vec_sort <- sort(vec)
vec_sort
# a b c f d e g 
# 1 1 1 1 2 3 5 

str(vec_sort)
# Named num [1:7] 1 1 1 1 2 3 5
# - attr(*, "names")= chr [1:7] "a" "b" "c" "f" ...

OUTPUT REQUIRED

A Named Logical Vector where in First 3 element of ascending order numeric vector to be TRUE, rest FALSE. Even if 4th element is same as first 3 elements. i.e. the lowest value. Using relational operators or by assigning it may be.

vec_sort
# a b c f d e g 
# 1 1 1 1 2 3 5 

TO

vec_sort
#    a     b     c     f     d     e     g 
# TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE 

Codes Attempted

1st

vec_sort[1:3] <- TRUE
vec_sort[4:length] <- FALSE

vec_sort
# a b c f d e g 
# 1 1 1 0 0 0 0 

Not Logical

str(vec_sort)
# Named num [1:7] 1 1 1 0 0 0 0
- attr(*, "names")= chr [1:7] "a" "b" "c" "f" ...

2nd

 vec_sort <= min(vec_sort)
 #    a     b     c     f     d     e     g 
 # TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE 

Here 4th variable f also comes up to be TRUE as the condition is set like that. it is minimum, but from minimum also, I want to set only top 3 to TRUE

Many more logical conditions attempted, but it all results in first 4 as TRUE and if I try assigning it to TRUE or FALSE it turns out to be a Named Numeric Vector showing hopefully 1 as TRUE and 0 as FALSE, but not ending up to be a Named Logical Vector.


Solution

  • setNames(as.logical(replace(replace(vec_sort, TRUE, FALSE), 1:3, TRUE)), names(vec_sort))
    #OR
    setNames(as.logical(replace(vec_sort * 0, 1:3, 1)), names(vec_sort))
    #OR
    setNames(c(rep(TRUE, 3), rep(FALSE, length(vec_sort)-3)), names(vec_sort))
    #OR
    replace(vec_sort == max(vec_sort) + 999, 1:3, TRUE)
    #   a     b     c     f     d     e     g 
    #TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE