2012-09-11 8 views
8

Estoy tratando de escribir un guión R para evaluar diferentes expresiones basadas en ajustar un valor dentro de los rangos. La idea es que si Length está dentro de un rango, se evaluará de una manera, y si se trata de un rango más largo, se evaluará de manera diferente.Sentencia de cambio R en las comparaciones

Puedo hacer que esto funcione con sentencias if/else, pero es bastante feo, y estoy seguro de que debe haber una manera mejor ... aquí está el código que funciona.

Length=8.2 

if (Length<1) 
    mode="Walk" 
else if (1<=Length & Length <5) 
    mode="bike" 
else if (5<=Length & Length <10) 
    mode="drive" 
else if (Length>=10) 
    mode="fly" 

que he estado tratando de hacer que algo funcione con el funcionamiento del detector, pero parece funcionar sólo con texto o números enteros ... ¿hay una manera de tener una sentencia switch que lleva a cabo evaluaciones en cada caso, como esto?

Length=3.5 

switch(Length, 
     (Length<1) mode="Walk" 
     (1<=Length & Length <5) mode="bike" 
     (5<=Length & Length <10) mode="drive" 
     (Length=>10) mode="fly" 
) 
+0

No sé si ayuda, pero propuse una edición para su código "feo" que lo hace mucho menos feo. – Superbest

+0

Aquí se proporcionó una solución que utiliza 'switch()' y 'match()' (mucho más tarde en 2014): http://stackoverflow.com/a/27279612/1103558 – noumenal

Respuesta

16

Aquí es una respuesta similar a la de Josh, pero utilizando findInterval:

Length <- 0:11 

cuts <- c(-Inf, 1, 5, 10, Inf) 
labs <- c("Walk", "bike", "drive", "fly") 

labs[findInterval(Length, cuts)] 
# [1] "Walk" "bike" "bike" "bike" "bike" "drive" "drive" 
# [8] "drive" "drive" "drive" "fly" "fly" 

También puede utilizar ifelse instrucciones anidadas, es una cuestión de gusto:

ifelse(Length < 1, "Walk", 
ifelse(Length < 5, "bike", 
ifelse(Length < 10, "drive", 
        "fly"))) 
# [1] "Walk" "bike" "bike" "bike" "bike" "drive" "drive" 
# [8] "drive" "drive" "drive" "fly" "fly" 
+0

OK, eso funciona, ¡gracias! y parece un poco más legible que el desastre que tuve. – mooseo

5

¿Lo que necesita es cut()?

Length <- 0:11 

cuts <- c(-Inf, 1, 5, 10, Inf) 
labs <- c("Walk", "bike", "drive", "fly") 

as.character(cut(Length, breaks = cuts, labels = labs, include.lowest=TRUE)) 
# [1] "Walk" "Walk" "bike" "bike" "bike" "bike" "drive" "drive" "drive" 
# [10] "drive" "drive" "fly" 
+0

Esto funcionaría muy bien para el ejemplo simplificado que publiqué, pero tal vez no tan bien como lo que realmente quiero hacer ... En lugar de simplemente elegir una etiqueta, necesito cada caso para evaluar una ecuación por separado. – mooseo

+0

@mooseo - Pero ahora tienes un vector de caracteres, que * puedes * alimentar a 'cambiar()' ... –

2

Usando dplyr de case_when declaración:

> Length=3.5 
> mode <- case_when(
       (Length < 1) ~ "Walk", 
       (1 <= Length & Length < 5) ~ "bike", 
       (5 <= Length & Length < 10) ~ "drive", 
       (Length >= 10) ~ "fly" 
     ) 
> mode 
[1] "bike" 
Cuestiones relacionadas