2017-10-13 4 views
0

Je viens de lire que la vectorisation augmente les performances et diminue considérablement le temps de calcul, et dans le cas de if(), le meilleur choix est ifelse().Comment vectoriser de si ifelse avec plusieurs instructions?

Mon problème est que je suis un peu si les déclarations dans une boucle, et chaque instruction if contient plusieurs missions, comme ce qui suit:

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 
    }}} 

Comment puis-je traduire en ifelse?

Merci d'avance!

+0

S'il vous plaît en revue [mcve ] –

+0

Merci! Évalué et mis à jour –

Répondre

0

Vous pouvez au moins convertir deux affectations en une seule. Ainsi, au lieu de

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

vous pouvez vous référer directement à la seule partie qui vous intéresse.

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

espoir que ça aide!

+1

merci! Il aide définitivement –

0

Il semble que je trouve la réponse à essayer de construire l'exemple:

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]))} 
2

Notez que vous n'avez pas besoin pour la boucle comme toutes les opérations utilisées sont vectorisés:

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