2016-02-11 21 views
6

Quando devo catena IfElse dichiarazioni, sembra che:Un modo intelligente per concatenare le dichiarazioni ifelse?

ifelse(input=="x","x1", 
     ifelse(input=="y","x2", 
       ifelse(input=="z","x3",NA))) 

C'è un modo più intelligente per fare questo? Sto pensando di creare tabelle, quindi unirmi o qualcosa di simile solo per rendere il codice un aspetto migliore?

+3

Utilizzare un vettore o un elenco con nome oppure osservare 'switch' o' factor'. – A5C1D2H2I1M1N2O1R2T1

+0

Trovo più catene ifelse più leggibili Se non indentate ogni nuovo ifelse ma aggiungete un'interruzione di riga prima di ', NA)))'. – Pekka

+0

Consiglierei l'uso di tabelle per qualsiasi cosa tranne le istruzioni 'ifelse' più semplici. Semplifica il debug e la comprensione in futuro. – Hugh

risposta

11

A parte i suggerimenti nei commenti si potrebbe anche usare match nel seguente modo.

Crea dati di esempio:

set.seed(1) 
vals_in <- c("x", "y", "z") # unique values in your input vector 
vec_in <- sample(vals_in, 10, replace = TRUE) # sample from vals_in to create input 
vals_out <- c("x1", "x2", "x3") # values to replace 

Ora, per sostituire la nidificato ifelse s si potrebbe fare:

vec_out <- vals_out[match(vec_in, vals_in)] 

Il risultato è

vec_out 
# [1] "x1" "x2" "x2" "x3" "x1" "x3" "x3" "x2" "x2" "x1" 

Un po 'di confronto di due approcci:

set.seed(1) 
vals_in <- letters 
vec_in <- sample(vals_in, 1e7, replace = TRUE) 
vals_out <- LETTERS 

system.time(vals_out[match(vec_in, vals_in)]) 
     User  System verstrichen 
     0.378  0.020  0.398 
system.time(unname(setNames(vals_out, vals_in)[vec_in])) 
     User  System verstrichen 
     1.020  0.062  1.084 
+0

Questo è bello. Ma qualche suggerimento su come affrontare altre condizioni di tipo come le disuguaglianze? – Pekka

+0

@Pekka, un piccolo esempio sarebbe bello provarlo. Ne hai uno in mente? –

+0

Beh, stavo pensando qualcosa del genere: 'x = 1:14; ifelse (x == 5, 'a', ifelse (x% in% c (1,4), 'b', ifelse (x <= 10, 'c', ifelse (x <= 12, 'd', 'e')))) ' – Pekka

8

Si può provare una funzione come questa:

choice <- function(input) { 
    switch(input, 
     "x"="x1", 
     "y"="x2", 
     "z"="x3", 
     NA) 
} 
#> choice("x") 
#[1] "x1" 
#> choice("z") 
#[1] "x3" 
#> choice("other") 
#[1] NA 
+0

@docendodiscimus Si può racchiudere questa funzione in 'sapply()' per trattare un vettore di input, come questo: 'sapply (my_vector, choice)', ma presumo che ciò non produrrà prestazioni molto veloci. – RHertel

5

Un'altra opzione sarebbe utilizzando setNames

unname(setNames(vals_out, vals_in)[vec_in]) 
#[1] "x1" "x2" "x2" "x3" "x1" "x3" "x3" "x2" "x2" "x1" 

NOTA: Preso l'esempio da @docendo posta discimus.

Problemi correlati