【问题标题】:how can I change a character to date-time type with ifelse?如何使用 ifelse 将字符更改为日期时间类型?
【发布时间】:2020-06-18 18:10:43
【问题描述】:

假设我想将“43843”这样的数字转换为日期时间格式(从excel读取的文件,所以某些文件的日期时间格式正确;但其他人显示一个字符,例如“43875”,即1899-12-30的天数);但有些已经是日期时间类型;所以我使用 ifelse 来判断列的类型然后应用 as.posixct 函数。但它似乎不起作用。我不知道为什么。

> tt <- as.POSIXct(c("2020-1-9","2020-2-1","2020-2-8"))
> dd1 <- tibble(tt,1:3)
> ts <- c("43843","43842","43844")
> dd2 <- tibble(tt=ts,1:3)
> dd1 %>% 
+     mutate(tt = ifelse(is.POSIXct(tt),tt,
+                        as.POSIXct(as.Date(as.numeric(tt), origin = "1899-12-30"))))
# A tibble: 3 x 2
          tt `1:3`
       <dbl> <int>
1 1578499200     1
2 1578499200     2
3 1578499200     3
> dd2 %>% 
+     mutate(tt = ifelse(is.POSIXct(tt),tt,
+                        as.POSIXct(as.Date(as.numeric(tt), origin = "1899-12-30"))))
# A tibble: 3 x 2
          tt `1:3`
       <dbl> <int>
1 1578873600     1
2 1578873600     2
3 1578873600     3

【问题讨论】:

  • 你从哪里得到is.POSIXct?我没有这样的功能。
  • 我很抱歉这个错误;它来自 {lubridate} package@thelatemail

标签: r date datetime tidyverse


【解决方案1】:

已经是日期时间类型的值仍然是字符,因为一列只能保存一种类型的数据,因此is.POSIXct 将不起作用。尝试以下方法:

library(dplyr)

dd2 %>%
   mutate(tt1 = replace(as.POSIXct(tt, format = "%Y-%m-%d %T"), 
                         grepl('^[0-9]*$', tt), NA), 
          tt = as.POSIXct(as.Date(as.numeric(tt), origin = "1899-12-30")),
          final = coalesce(tt1, tt))

这首先会创建一个POSIXct 类型的列(tt1),它的数据值具有日期和时间,NA 用于日期。然后我们将日期(即数字)更改为POSIXct 格式,然后使用coalesce 组合列。

【讨论】:

  • 这不适用于 dd1: dd1 %>% mutate(tt1 = replace(as.POSIXct(tt, format = "%Y-%m-%d %T"), grepl(' ^[0-9]*$', tt), NA), tt = as.POSIXct(as.Date(as.numeric(tt), origin = "1899-12-30")), final = coalesce(tt1 , tt)) 我想要两个条件的函数,因为我不知道我遇到了哪个条件。我从光盘中读取了数百个 EXCEL 文件。
  • @Z.Zhang 如果我使用您示例中的dd1 并运行上面的代码,最后的列会给我2020-01-09 00:00:00、2020-02-01 00:00:00 和2020-02-08 00:00:00。您期望的输出是什么?
  • 是的,你是对的,我弄错了;该代码只适用于我@Ronak Shah
【解决方案2】:

我认为这更像是一个if() else 问题,而不是一个矢量化的ifelse() 问题。 请注意此处的时区问题,因为您要在系统时区中定义时间,并且还要提供与 GMT 没有偏移的数据。

无论如何...

convfun <- function(x) {
  if(is.POSIXct(x)) {x} else {
    as.POSIXct(format(as.POSIXct(as.numeric(x)*86400, origin="1899-12-30", tz="UTC")))
  }
}

dd1 %>% mutate(tt = convfun(tt))
## A tibble: 3 x 2
#  tt                  `1:3`
#  <dttm>              <int>
#1 2020-01-09 00:00:00     1
#2 2020-02-01 00:00:00     2
#3 2020-02-08 00:00:00     3

dd2 %>% mutate(tt = convfun(tt))
## A tibble: 3 x 2
#  tt                  `1:3`
#  <dttm>              <int>
#1 2020-01-13 00:00:00     1
#2 2020-01-12 00:00:00     2
#3 2020-01-14 00:00:00     3

在同一时区检查两者:

(dd1 %>% mutate(tt = convfun(tt)))$tt
#[1] "2020-01-09 AEST" "2020-02-01 AEST" "2020-02-08 AEST"
(dd2 %>% mutate(tt = convfun(tt)))$tt
#[1] "2020-01-13 AEST" "2020-01-12 AEST" "2020-01-14 AEST"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多