jpd527
jpd527

Reputation: 1551

CASE WHEN equivalent in R for a vector

I have a matrix with two columns, the first of which is sometimes NA, and would like to create a third column that is the value of the first, unless it is NA, in which case it takes the value of the second. I have a for loop so far, but I'm sure there's a MUCH better way to do this in R.

matrixA$Age3 <- 1:length(matrixA$Age)
for(i in 1:length(matrixA$Age3))
{
  if(!is.na(matrixA$Age[i]))
  {
    matrixA$Age3[i] = matrixA$Age[i]
  }else
  {
    matrixA$Age3[i] = matrixA$Age2[i]
  }
}

Upvotes: 0

Views: 2318

Answers (2)

Carl Witthoft
Carl Witthoft

Reputation: 21532

maybe , just for fun,

matrix$Age3 <- sapply(1:nrow(matrix), function(j) matrix[j,(2-!is.na(foo[j,1]))])

(With apologies to CSGillespie if he had anything like this, since he deleted his)

EDIT: As eddi properly suggested, here is some expansion and testing of my ideas. I am now properly and publicly shamed for my incorrect assumption that "ifelse" was a timepig. switch is easier to read, but at least for this small dataset and limited set of switches, the time difference is not significant. (I may well have fubared the exact cutoff values but the effective operation of these two functions is what matters here).

# foo is a 2e4 row by 5 column matrix of runif values 

ifelse4 <- function(foo) ifelse(foo[,1] > 0.8,foo[,2],ifelse(foo[,1] > 0.6,foo[,3],ifelse(foo[,1] > .4 , foo[,4],ifelse(foo[,1] > .2 , foo[,5], foo[,1])))) 

switch4l <- function(foo) {

 for(j in 1:nrow(foo)) {
         switch( ceiling(foo[j,1]*5),
            foo[j,1],
            foo[j,5],
            foo[j,4],
            foo[j,3],
            foo[j,2] )
        }
        }


    microbenchmark(ifelse4(foo),switch4l(foo),times=10)

    Unit: milliseconds
          expr      min       lq   median       uq      max neval
  ifelse4(foo) 31.37346 31.87336 32.21567 32.44509 33.21182    10
 switch4l(foo) 28.03629 28.31339 28.61871 28.99588 29.78014    10

Upvotes: 1

Rohit Das
Rohit Das

Reputation: 2042

matrix$Age3 <- ifelse(!is.na(matrix$Age),matrix$Age,matrix$Age2)

Upvotes: 2

Related Questions