【问题标题】:IFELSE in R returning incorrect valuesR中的IFELSE返回不正确的值
【发布时间】:2020-02-27 21:00:34
【问题描述】:

我有一个包含手动输入的分类值的数据框,并且有几个错误。有人清理了坏数据,我将其加载到 R 中并将其与我的其余数据合并。到目前为止一切都很好。

例如,假设这是我在“Value”列中的原始数据(好数据和坏数据的混合)以及“Value_Clean”列中坏数据的更正。显然这是一个小例子,但我的实际数据框有几十个不同值的更正和几千行。

test <- data.frame(ID = c(1, 2, 3)
               , Value = c("Discuss plan", "Discuss plan", "Discuss paln")
               , Value_Clean = c(NA, NA, "Discuss plan"))

我想创建一个名为“Value_Final”的新列,其中包含 ID 1、2 和 3 的“讨论计划”。

我应该能够用 ifelse 来完成这个似乎很简单:

test$Value_Final <- ifelse(is.na(test$Value_Clean), test$Value, test$Value_Clean)

但是,当我这样做时,我会得到以下信息:

> test
  ID        Value  Value_Clean Value_Final
1  1 Discuss plan         <NA>           2
2  2 Discuss plan         <NA>           2
3  3 Discuss paln Discuss plan           1

什么鬼?我觉得我在 R 中用 ifelse 做了类似的事情而没有遇到这个问题,那么发生了什么?

谢谢!

【问题讨论】:

  • 请将数据类型更改为字符以获得结果 test$Value_Clean = as.character(test$Value_Clean) test$Value = as.character(test$Value) test$Value_Final

标签: r if-statement


【解决方案1】:

这是factor 强制转换为整数存储值的情况。可以在创建 data.frame 时使用 stringsAsFactors = FALSE 进行更正

test <- data.frame(ID = c(1, 2, 3)
                , Value = c("Discuss plan", "Discuss plan", "Discuss paln")
                , Value_Clean = c(NA, NA, "Discuss plan"), stringsAsFactors = FALSE)
ifelse(is.na(test$Value_Clean), test$Value, test$Value_Clean)
#[1] "Discuss plan" "Discuss plan" "Discuss plan"

或者如果数据已经创建,那么可以转换为characteras.character

test[1:2] <- lapply(test[1:2], as.character)

或在ifelse 中执行此操作

ifelse(is.na(test$Value_Clean), as.character(test$Value), 
         as.character(test$Value_Clean))

【讨论】:

    【解决方案2】:

    ifelse的dplyr版本没有这个问题

    ifelse(is.na(test$Value_Clean), test$Value, test$Value_Clean)
    
    # [1] 2 2 1
    
    
    dplyr::if_else(is.na(test$Value_Clean), test$Value, test$Value_Clean)
    
    # [1] Discuss plan Discuss plan Discuss plan
    # Levels: Discuss paln Discuss plan
    

    仅供参考,对于这个特定示例,您可以使用 coalesce 代替

    dplyr::coalesce(test$Value_Clean, test$Value)
    # [1] Discuss plan Discuss plan Discuss plan
    # Levels: Discuss plan
    

    【讨论】:

    • 这非常有帮助,感谢您提供有关合并的提示!
    【解决方案3】:

    您可以尝试 dplyr 和 tibbles 作为替代方案:

    library(dplyr)
    
    tibble(ID = c(1, 2, 3)
           , Value = c("Discuss plan", "Discuss plan", "Discuss plan")
           , Value_Clean = c(NA, NA, "Discuss plan")) %>% 
      mutate(Value_Final = ifelse(is.na(Value_Clean), Value, Value_Clean))
    

    默认情况下,tibbles 不会将字符列转换为因子,这在很多情况下都很方便

    编辑: 使用 as_tibble(dataframe) 将现有数据帧转换为 tibble

    【讨论】:

    • 请注意,as_tibble 不会将因子转换为字符,因此您仍然会在此处获得 ifelse 的数字输出
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    • 2016-10-09
    • 2021-10-26
    • 2015-10-13
    • 2014-12-06
    相关资源
    最近更新 更多