2012-09-11 54 views
8

我正在尝试编写一个R脚本来根据拟合范围内的值来评估不同的表达式。这个想法是,如果长度在一个范围内,它将被单向评估,如果长度在一个更长的范围内,它将得到不同的评估。比较R switch语句

我可以使用if/else语句来完成这项工作,但它非常难看,而且我确定必须有更好的方法......这里是可用的代码。

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" 

我一直在试图与开关功能的东西的工作,但它似乎只能用文字或整数......工作是有办法有,在每种情况下,这样进行评价switch语句这样?

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

不知道它是否有帮助,但我提出了一个编辑“丑陋”的代码,使其不那么难看。 – Superbest

+0

这里给出了一个使用'switch()'和'match()'的解决方案(2014年晚些时候):http://stackoverflow.com/a/27279612/1103558 – noumenal

回答

16

这里是一个类似的答案,Josh的,但使用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" 

您也可以使用嵌套ifelse语句,这是一个品味的问题:

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

好吧,那可行,谢谢!而且它看起来比我的烂摊子更具可读性。 – mooseo

5

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

这对我发布的简化示例非常有用,但可能不是我真正想做的事情...而不是仅仅选择一个标签,我需要每个案例来评估一个单独的等式。 – mooseo

+0

@mooseo - 但现在你有一个角色矢量,你*可以*喂给'switch()'...... –

2

使用dplyr的case_when声明:

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