【问题标题】:Nested if else statement in R - 'else' statement executed even when 'if' statement is TRUER中的嵌套if else语句 - 即使'if'语句为TRUE,'else'语句也会执行
【发布时间】:2020-09-06 18:02:48
【问题描述】:

我有一个包含 2 列的数据框:df$adf$b。 我需要使用 2 组单独的条件根据 df$b 的值计算列 df$c 的值。应应用哪组条件取决于df$a 的值。

我试图通过编写嵌套的ifelse 语句来解决这个问题。

# A subset of my data
    a <- c(4211L, 2660L, 2839L, 3967L, 3167L, 2755L, 1680L, 2400L, 1173L, 1301L, 2370L, 2366L, 411L, 615L, 1382L, 826L, 717L, 401L, 177L, 82L, 579L, 246L)
    b <- c(0.213, 0.102, 0.092, 0.121, 0.093, 0.0918, 0.0241, 0.060, 0.008, 0.003, 0.0385, 0.0368, -0.0529, -0.0697, 0.0192, -0.0346, -0.053, NA, -0.098, -0.139, -0.137, -0.0697)
    df <- data.frame(a,b)

我想在df$a &lt;1000时使用第一组条件,在df$a&gt;=1000时使用第二组条件。这是我的代码:

df$c <- if (df$a < 1000) {
          ifelse(df$b <= -0.2, '1',
                 ifelse(df$b > -0.2 & df$b <= -0.1, '2',
                        ifelse(df$b > -0.1 & df$b <= 0.0, '3',
                               ifelse(df$b > 0.0 & df$b <= 0.1, '4',
                                      '5'))))
        } else {
          ifelse(df$b <= 0.0, '1',
                 ifelse(df$b > 0.0 & df$b <= 0.1, '2',
                        ifelse(df$b > 0.1 & df$b <= 0.2, '3',
                               ifelse(df$b > 0.2 & df$b <= 0.3, '4',
                                      '5'))))
        }

但是,代码会根据else 语句中的条件计算所有df$c 值,即使(df$a &lt; 1000)TRUE 也是如此。有谁知道是什么导致了这个错误?我收到以下警告消息:

Warning message:
In if (df$a < 1000) { :
  the condition has length > 1 and only the first element will be used

【问题讨论】:

    标签: r dataframe if-statement conditional-statements


    【解决方案1】:

    我们可以使用findInterval

    df$c <- with(df, ifelse(a < 1000, findInterval(b, seq(-0.2, 0.1, 0.1)), 
                                      findInterval(b, seq(0, 0.3, 0.1))) + 1)
    df$c
    # [1]  4  3  2  3  2  2  2  2  2  2  2  2  3  3  2  3  3 NA  3  2  2  3
    

    【讨论】:

      【解决方案2】:

      您也可以使用ifelse,因为if 是非矢量化的。我会使用像cut 这样的函数来简化代码:

      a <- c(4211L, 2660L, 2839L, 3967L, 3167L, 2755L, 1680L, 2400L, 1173L, 1301L, 2370L, 2366L, 411L, 615L, 1382L, 826L, 717L, 401L, 177L, 82L, 579L, 246L)
      b <- c(0.213, 0.102, 0.092, 0.121, 0.093, 0.0918, 0.0241, 0.060, 0.008, 0.003, 0.0385, 0.0368, -0.0529, -0.0697, 0.0192, -0.0346, -0.053, NA, -0.098, -0.139, -0.137, -0.0697)
      df <- data.frame(a,b)
      
      df$c <- ifelse(df$a < 1000,
                     cut(df$b, breaks = c(-Inf, -0.2, -0.1, 0.0, 0.1, +Inf), 
                         labels = as.character(1:5)),
                     cut(df$b, c(-Inf, 0, 0.1, 0.2, 0.3, +Inf), 
                         as.character(1:5)))
      df
      
      # a       b  c
      # 1  4211  0.2130  4
      # 2  2660  0.1020  3
      # 3  2839  0.0920  2
      # 4  3967  0.1210  3
      # 5  3167  0.0930  2
      # 6  2755  0.0918  2
      # 7  1680  0.0241  2
      # ....
      

      【讨论】:

      • 但是如果 max(df$b) 小于之前的 break 会不会导致错误?
      • 你可以使用breaks = c(-Inf, -0.2, .., +Inf)
      • 我的男人!我注意到使用 -Inf 实际上会返回所有正确的值,而您的初始解决方案有时会为最低或最高 df$b 数字返回不正确的值。
      猜你喜欢
      • 2013-03-13
      • 2019-05-20
      • 1970-01-01
      • 2019-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多