Using "larger than" / "smaller than" on a vector with both numerical values and characters

Viewed 37

This seems like the most silly question ever, but I cannot figure out what is going on..

I have data as follows:

test <- c("A", 1, 2)    
out <- rep("ON", 3)

I want to replace values that have a numerical value larger than 1 (so 2 should be OFF).

If I do:

out[test > 1] <- "OFF"   
out

I get:

[1] "OFF" "ON"  "OFF"

Because apparently "A" > 1 = TRUE

If I do

out[as.numeric(test > 1)] <- "OFF" 

I get:

[1] "OFF" "ON"  "ON" 

Even though as.numeric(test > 1) is:

[1] 1 0 1

and as.numeric("A") is NA, and NA > 1 is NA.

What is the right way to get these values?

EDIT

Because the function that I am using throws an error if there is a warning, I tried to combine the solution of akrun and Dmitry (because that solution throws a warning).

However, for some reason:

test <- c("25", "38", "40", "38", "207", "16", "31", "18", "22", "20", 
"3", "19", "4", "43", "20", "15", "21", "36", "36", "23", "33", 
"31", "48")
grepl("^[0-9.]+$", test) & test < 10

is

[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[20] FALSE FALSE FALSE FALSE
2 Answers

One approach may be to use a simple ifelse statement on the test vector without the need for the out vector:

ifelse(test %in% "2", "OFF","ON")

# [1] "ON"  "ON"  "OFF"

This would only work for the test dataset you provided, but if there was a limit to what the values greater than 2 could be you could expand it:

test <- c("A", 1, 2, 999)
ifelse(test %in% as.character(2:1000), "OFF","ON")

# [1] "ON"  "ON"  "OFF" "OFF"
test <- c("A", 1, 2)    
out <- rep("ON", 3)
idx <- as.numeric(test) > 1
is.na(idx) <- FALSE
out[idx] <- 'OFF'
out
[1] "ON"  "ON" "OFF" 
Related