Reputation: 1551
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
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
Reputation: 2042
matrix$Age3 <- ifelse(!is.na(matrix$Age),matrix$Age,matrix$Age2)
Upvotes: 2