【问题标题】:Issue with logical operators in R, using ifelseR中的逻辑运算符问题,使用ifelse
【发布时间】:2020-09-24 23:01:18
【问题描述】:

下面是我正在使用的代码。这个想法是我们有一个变量“habitaciones”,它计算酒店的房间数量。我创建了一个名为 hrango 的新变量,它的范围基于房间的数量。 20 人以下的酒店是小型酒店,21 到 40 人是中型酒店,40 人以上是大型酒店。您可以看到我如何尝试使用运算符来处理它。

我运行此代码时的问题是,任何少于 10 个房间的酒店都被标记为大,而任何超过 100 个房间的酒店都被标记为小,我似乎无法弄清楚为什么。我开始使用基于“替换”的代码,该代码无法正常工作,移至 ifelse,但仍然无法获得我想要的结果。

任何帮助将不胜感激。

full_data <- full_data %>% 
  mutate (hrango = ifelse(habitaciones < 21, "Hoteles Pequenos",
                          ifelse(habitaciones > 20 & habitaciones < 41, "Hoteles Medios",
                                 ifelse(habitaciones > 40, "Hoteles Grandes", hrango)
                                        )
                                        )
                                       )

【问题讨论】:

  • 请添加一个可重现的例子
  • 会考虑使用dplyr::case_when()而不是复杂的嵌套ifelse()
  • 您的问题可能与您在条件中使用“&”而不是“&&”这一事实有关。请下次上传一些我们可以使用的数据。
  • @Lluís,这是不正确的,&amp; 在这里是合适的,&amp;&amp; 是错误的。 (我同意样本数据。)(我根据habitacionesfull_data 中的一列的假设做出&amp;-vs-&amp;&amp; 的确定。)

标签: r if-statement replace


【解决方案1】:
  1. 一般来说,base R 的ifelse 有一些包袱,即它会掉级。例如,

    ifelse(c(T,F), rep(Sys.time(),2), rep(Sys.time(),2))
    # [1] 1591376254 1591376254
    

    既然你已经在使用dplyr,我建议你考虑dplyr::if_else

    if_else(c(T,F), rep(Sys.time(),2), rep(Sys.time(),2))
    # [1] "2020-06-05 09:57:57 PDT" "2020-06-05 09:57:57 PDT"
    

    data.table::fifelse也不错。)

  2. 当我看到嵌套的ifelses 时,我认为case_when 会更好。它并不经常更快(大致相同),但它更具可读性,因此更易于维护。

    full_data %>%
      mutate(
        hrango = case_when(
          habitaciones < 21                     ~ "Hoteles Pequenos",
          habitaciones > 20 & habitaciones < 41 ~ "Hoteles Medios",
          habitaciones > 40                     ~ "Hoteles Grandes",
          TRUE ~ hrango)
      )
    

    由于case_when 在第一个 true 之后停止评估(针对每个元素),您可以稍微缩短一下:

    full_data %>%
      mutate(
        hrango = case_when(
          habitaciones < 21 ~ "Hoteles Pequenos",
          habitaciones < 41 ~ "Hoteles Medios",
          habitaciones > 40 ~ "Hoteles Grandes",
          TRUE ~ hrango)
      )
    
  3. 此外,由于您只是在连续范围的值中查找,您可以使用cut

    full_data %>%
      mutate(
        hrango = cut(hrango, c(-Inf, 20, 40, Inf),
                     labels = c("Hoteles Pequenos", "Hoteles Medios", "Hoteles Grandes")),
        hrango = as.character(hrango)
      )
    

    as.character 的第二个赋值是因为cut 返回factor,我推断你想要character

    另一个注意事项:我推断您正在使用integers,因为您的条件重叠。 case_when 解决方案仍然有效,但如果您的数据是 numeric,那么您可能需要重新考虑您的界限以确保您获得所需的数据。由于cut默认为“右闭”(right=TRUE),它会给你左开,所以(0,20](20,40]意味着20将匹配第一个,20.1和21将匹配第二个,等等.

【讨论】:

  • 我认为@r2evans 你希望case_when 的最后一行是TRUE ~ NA_character_,但我同意它更容易阅读和修改
  • @ChuckP 你为什么要TRUE ~ NA_character_?检查OP给出的ifelse语句,如果一切都失败,返回hrango
  • @ChuckP,也许吧。我要脱离原始代码,所以我想我会保持一致。
  • @ChuckP,另一个想法:它可能是NaN,在这种情况下,OP 可能希望保留“数字”、NANaN 之间的差异。身份证
  • 啊,我假设我们正在从头创建hrango,在这种情况下,尝试将hrango 放入是不可能的。猜猜这就是猜测 OP 数据的问题。我的道歉
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-21
  • 1970-01-01
相关资源
最近更新 更多