【问题标题】:ifelse function problem defining the correct condition [duplicate]定义正确条件的ifelse函数问题[重复]
【发布时间】:2020-07-05 13:27:42
【问题描述】:

我无法通过搜索功能找到以下问题的答案:

为什么给定的ifelse() 条件不能按我的预期工作?

我得到了一个数据集,它错误地有一个日期的开放文本字段,因此我得到了人们填写日期的多种方式。到目前为止,我真的接近了一些可用的东西,但我打算下一步制作每个毫米2000 年之前的 /yy 条目通过 ifelse 函数输入的 mm/19yy 不会给我正确的结果:

Dates <- c("10/19", "04/2019", "O5/1992", "03/92")

ifelse(str_length(Dates)==5 & str_sub(Dates,4,5)>20, stri_sub(Dates, 4, 3) <- 19, Dates)

结果如下:

[1] "10/1919"   "04/192019" "O5/191992" "19"   

虽然我希望它看起来像这样:

1] "10/19"   "04/2019" "O5/1992" "03/1992"

非常感谢任何帮助!

【问题讨论】:

  • 错误是在ifelse中赋值。这个stri_sub(Dates, 4, 3) &lt;- 19 不起作用。
  • 尽管 Ronak Shah 提供了一个非常有帮助的答案,让我走到了终点,但还是感谢您的回答。

标签: r date if-statement


【解决方案1】:

这并没有给出您所显示的预期输出,但我认为最好将日期转换为标准日期,以便更容易使用它们。

Dates <- c("10/19", "04/2019", "O5/1992", "03/92")
new_Date <- as.Date(lubridate::parse_date_time(paste0('1/', Dates), c('dmY', 'dmy')))
new_Date
#[1] "2019-10-01" "2019-04-01" "1992-05-01" "1992-03-01"

然后你可以format这些日期你想要的方式:

format(new_Date, '%Y-%m')
#[1] "2019-10" "2019-04" "1992-05" "1992-03"

【讨论】:

    【解决方案2】:

    我建议不要在单个表达式中执行此操作,而是将其分开以提高可读性:

    parts = str_split(dates, '/')
    year = as.integer(map_chr(parts, `[[`, 2L))
    months = as.integer(map_chr(parts, `[[`, 1L))
    result = ifelse(
        str_length(dates) == 5L & year > 20 & year < 100,
        paste0(months, '/', '19', as.character(year)),
        dates
    )
    

    此代码还显式处理数据类型转换,这使代码更具表现力并有助于发现错误 — 例如,您的第三次约会不小心使用了 O(大写 o)而不是 0,我之所以注意到这是因为我的代码抱怨无效转换。

    基本上我也同意 Ronak 的回答:您似乎想要的输出是不一致的,通常应该避免使用统一格式,这会导致代码更简单,正如 Ronak 的回答所示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-11
      • 1970-01-01
      • 2017-10-23
      • 2019-03-12
      • 1970-01-01
      • 2021-09-24
      • 1970-01-01
      • 2017-04-24
      相关资源
      最近更新 更多