0

I just read that vectorization increases performance and lowers significantly computation time, and in the case of if() else , best choice is ifelse().

My problem is I got some if statements inside a for loop, and each if statement contains multiple assignments, like the following:

x <- matrix(1:10,10,3)

criteria <- matrix(c(1,1,1,0,1,0,0,1,0,0,
                     1,1,1,1,1,0,0,1,1,0,
                     1,1,1,1,1,1,1,1,1,1),10,3) #criteria for the ifs
output1 <- rep(list(NA),10) #storage list for output
for (i in 1:10) {
  if (criteria[i,1]>=1) {
    output1[[i]] <- colMeans(x)
    output1[[i]] <- output1[[i]][1] #part of the somefunction output
  } else { 
    if(criteria[i,2]>=1) {
      output1[[i]] <- colSums(x)
      output1[[i]] <- output1[[i]][1] #the same
    } else {
      output1[[i]] <- colSums(x+1)
      output1[[i]] <- output1[[i]][1] #the same
    }}}

How can I translate this into ifelse?

Thanks in advance!

Oscar L
  • 35
  • 6

3 Answers3

2

Note that you don't need a for loop as all operations used are vectorized:

output2 <- ifelse(criteria[, 1] >= 1, 
             colMeans(x)[1], 
             ifelse(criteria[, 2] >= 1, 
               colSums(x)[1], 
               colSums(x+1)[1]))

identical(output1, as.list(output2))
## [1] TRUE
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
0

At least you can convert two assignments into one. So instead of

output[[i]] <- somefunction(arg1,arg2,...)
output[[i]] <- output[[i]]$thing #part of the somefunction output

you can refer directly to the only part you are interested in.

output[[i]] <- somefunction(arg1,arg2,...)$thing #part of the somefunction output

Hope that it helps!

Heikki
  • 2,214
  • 19
  • 34
0

It seems I found the answer trying to build the example:

    output2 <- rep(list(NA),10) #storage list for output
    for (i in 1:10) {
  output2[[i]] <- ifelse(criteria[i,1]>=1,
                        yes=colMeans(x)[1],
                        no=ifelse(criteria[i,2]>=1,
                                  yes=colSums(x)[1],
                                  no=colSums(x+1)[1]))}
Oscar L
  • 35
  • 6