嵌套if语句 - R.

时间:2016-10-11 13:25:21

标签: r if-statement

我遇到多个if语句的问题。输出总是取自第一个条件,即使条件不正确。任何人都可以指出我做错了什么?

代码:

for(i in 1:length(data_model3$Gewicht)){
    if (data_model3$Gewicht[i] < 1){
      data_model3$LIXshipping <- 3.26 
    }
    else if (data_model3$Gewicht[i] > 1 & data_model3$Gewicht[i] < 2){
      data_model3$LIXshipping <- 3.26 
    }
    else if (data_model3$Gewicht[i] > 2 & data_model3$Gewicht[i] < 3){
      data_model3$LIXshipping <- 3.86 
    }
    else if (data_model3$Gewicht[i] > 3 & data_model3$Gewicht[i] < 4){
      data_model3$LIXshipping <- 3.86 
    }
    else if (data_model3$Gewicht[i] > 4 & data_model3$Gewicht[i] < 5){
      data_model3$LIXshipping <- 3.86 
    }
    else if (data_model3$Gewicht[i] > 5 & data_model3$Gewicht[i] < 10){
      data_model3$LIXshipping <- 4.39 
    }
    else if (data_model3$Gewicht[i] > 10 & data_model3$Gewicht[i] < 20){
      data_model3$LIXshipping <- 4.81 
    }
    else if (data_model3$Gewicht[i] > 20 & data_model3$Gewicht[i] < 31.5){
      data_model3$LIXshipping <- 6.34 
    }
    else 
      data_model3$LIXshipping <- 17.09 
}

输出:

count_code  Gewicht LIXshipping
281         4.67    3.26
683         3.34    3.26
903         14.56   3.26
7390        14.62   3.26
2778        2.86    3.26
2778        10.37   3.26

对于你们中的一些人来说这可能是一个完全基本的问题......但我不知道如何解决它 安德拉兹

5 个答案:

答案 0 :(得分:4)

这可以通过一行(数据+一行)来完成:

data_model3 <- data.frame(Gewicht=1:40)
data_model3$LIXshipping <- as.numeric(as.character(cut(data_model3$Gewicht, breaks=c(0,2,5,10,20,31.5, 100), labels=c(3.26, 3.86, 4.39, 4.81, 6.34, 17.09), right=FALSE)))

答案 1 :(得分:3)

我把规则放在一张桌子上......

library(data.table)
setDT(df)

rules = data.table(
  Gewicht = c(1:5, 10, 20, 31.5, Inf), 
  v = c(3.26, 3.26, 3.86, 3.86, 3.86, 4.39, 4.81, 6.34, 17.09)
)


   Gewicht     v
1:     1.0  3.26
2:     2.0  3.26
3:     3.0  3.86
4:     4.0  3.86
5:     5.0  3.86
6:    10.0  4.39
7:    20.0  4.81
8:    31.5  6.34
9:     Inf 17.09

然后使用“滚动连接”来应用它们

DF[, v := rules[DF, on="Gewicht", roll=-Inf, v] ]


    Gewicht     v
 1:       0  3.26
 2:       2  3.26
 3:       4  3.86
 4:       6  4.39
 5:       8  4.39
 6:      10  4.39
 7:      12  4.81
 8:      14  4.81
 9:      16  4.81
10:      18  4.81
11:      20  4.81
12:      22  6.34
13:      24  6.34
14:      26  6.34
15:      28  6.34
16:      30  6.34
17:      32 17.09
18:      34 17.09
19:      36 17.09
20:      38 17.09
21:      40 17.09
    Gewicht     v

数据:

DF = data.frame(Gewicht = seq(0,40,by=2))

答案 2 :(得分:0)

这不是直接回答这个问题,但我想提出带有矢量化ifelse的代码看起来像@akrun和@Tim所建议的那样,加上我的一些优化:

data_model3 <- data.frame(Gewicht=1:40)

data_model3$LIXshipping <- 
    ifelse (data_model3$Gewicht < 2,  3.26,
    ifelse (data_model3$Gewicht < 5,  3.86,
    ifelse (data_model3$Gewicht < 10, 4.39,
    ifelse (data_model3$Gewicht < 20, 4.81,
    ifelse (data_model3$Gewicht < 31.5, 6.34, 17.09)
))))

结果如下:

> data_model3
   Gewicht LIXshipping
1        1        3.26
2        2        3.86
3        3        3.86
4        4        3.86
5        5        4.39
6        6        4.39
7        7        4.39
8        8        4.39
9        9        4.39
10      10        4.81
11      11        4.81
12      12        4.81
13      13        4.81
14      14        4.81
15      15        4.81
16      16        4.81
17      17        4.81
18      18        4.81
19      19        4.81
20      20        6.34
21      21        6.34
22      22        6.34
23      23        6.34
24      24        6.34
25      25        6.34
26      26        6.34
27      27        6.34
28      28        6.34
29      29        6.34
30      30        6.34
31      31        6.34
32      32       17.09
33      33       17.09
34      34       17.09
35      35       17.09
36      36       17.09
37      37       17.09
38      38       17.09
39      39       17.09
40      40       17.09

我删除了冗余条件(当分配给变量的值与前一个相同时)。你不需要像data_model3$Gewicht[i] > 1 & data_model3$Gewicht[i] < 2那样的双重防护,因为第一个条件已经在之前的if语句中进行了测试。

请注意,当输入正好为1,2,3等时,原始代码不会执行任何操作,因为您只使用了严格的比较运算符<>,但通常我们至少使用<=>=中的一个来保护所有案例。我认为这是一个错误,并将它们优化掉了。

希望这有帮助。

答案 3 :(得分:0)

您可以尝试以下方法:

require(data.table)
setDT(data_model3)
data_model3[, LIXshipping:= ifelse(Gewicht < 2 & Gewicht != 1, 3.26,
                                   ifelse(Gewicht > 2 & Gewicht < 5 & !(Gewicht %in% c(3, 4)), 3.86,
                                          ifelse(Gewicht > 5 & Gewicht < 10, 4.39,
                                                 ifelse(Gewicht > 10 & Gewicht < 20, 4.81,
                                                        ifelse(Gewicht > 20 & Gewicht < 31.5, 6.34, 17.09)))))]

我根据您分配给他们的值缩短了某些类别(例如,您为类别1和2分配了相同的运费值) 至于你在代码中做错了什么,你应该将值分配给data_model3$LIXshipping[i],所以data_model3$LIXshipping[i] <- 4.81

答案 4 :(得分:-1)

我忘了在我的代码中索引 data_model3 $ LIXshipping [i] 。谢谢@jogo指出来。

for(i in 1:length(data_model3$Gewicht)){
        if (data_model3$Gewicht[i] < 1){
          data_model3$LIXshipping[i] <- 3.26 
        }
        else if (data_model3$Gewicht[i] > 1 & data_model3$Gewicht[i] < 2){
          data_model3$LIXshipping[i] <- 3.26 
        }
        else if (data_model3$Gewicht[i] > 2 & data_model3$Gewicht[i] < 3){
          data_model3$LIXshipping[i] <- 3.86 
        }
        else if (data_model3$Gewicht[i] > 3 & data_model3$Gewicht[i] < 4){
          data_model3$LIXshipping[i] <- 3.86 
        }
        else if (data_model3$Gewicht[i] > 4 & data_model3$Gewicht[i] < 5){
          data_model3$LIXshipping[i] <- 3.86 
        }
        else if (data_model3$Gewicht[i] > 5 & data_model3$Gewicht[i] < 10){
          data_model3$LIXshipping[i] <- 4.39 
        }
        else if (data_model3$Gewicht[i] > 10 & data_model3$Gewicht[i] < 20){
          data_model3$LIXshipping[i] <- 4.81 
        }
        else if (data_model3$Gewicht[i] > 20 & data_model3$Gewicht[i] < 31.5){
          data_model3$LIXshipping[i] <- 6.34 
        }
        else 
          data_model3$LIXshipping[i] <- 17.09 
}