【问题标题】:Splitting a column into date/time in tidyverse在 tidyverse 中将列拆分为日期/时间
【发布时间】:2020-10-05 11:08:20
【问题描述】:

我承认有多个类似的问题,但到目前为止我还没有找到适合我的答案,可能是因为 AM/PM。我不想删除后者。

我有一个专栏Trip Start Timestamp,看起来像

12/01/2019 12:30:00 AM
12/01/2019 12:31:00 AM
12/01/2019 12:32:00 AM 

我正在尝试删除 AM/PM 并拆分为两个变量 Start dateStart time

理想输出:

Start date Start time
12/01/2019 12:30:00 AM

我想把它当作时间序列来阅读。

到目前为止我的最佳猜测

Date <- format(as.POSIXct(strptime(taxi_2020$`Trip Start Timestamp`, "%d/%m/%Y %H:%M:S")), format = "%m/%d/%Y")
Time <- format(as.POSIXct(strptime(taxi_2020$`Trip Start Timestamp`, "%d/%m/%Y %H:%M:S")), format = "%H:%M:S")
head(Date)
head(Time)

给我

[1] NA NA NA NA NA NA
[1] NA NA NA NA NA NA

更新

看起来带有时间和日期的列的格式存在一些问题。

dput可以找到here

到目前为止,@Ronak Shah 的解决方案有效。从技术上讲,我终于分离了数据,但可能发现了UTF-8的另一个问题

【问题讨论】:

    标签: r date split tidyverse


    【解决方案1】:

    由于您使用tidyverse 标记了此内容,因此这里有一个使用lubridate 的简单方法:

    library(dplyr)
    library(lubridate)
    data %>%
      mutate(Date = as.Date(mdy_hms(`Trip Start Timestamp`)), 
             Time = format(mdy_hms(`Trip Start Timestamp`), "%I:%M:%S %p"))
    #    Trip Start Timestamp       Date        Time
    #1 12/01/2019 12:30:00 AM 2019-12-01 12:30:00 AM
    #2 12/01/2019 12:31:00 AM 2019-12-01 12:31:00 AM
    #3 12/01/2019 12:32:00 AM 2019-12-01 12:32:00 AM
    

    示例数据

    data <- structure(list(`Trip Start Timestamp` = c("12/01/2019 12:30:00 AM", 
    "12/01/2019 12:31:00 AM", "12/01/2019 12:32:00 AM")), class = "data.frame", row.names = c(NA, 
    -3L))
    

    【讨论】:

    • 非常感谢,你是tidyverse中的第一个,所以我会接受你的回答。
    • 错误:列 Time 的长度必须为 4137294(行数)或 1,而不是 3。
    • 代码现在可以工作,但初始列 Trip Start Timestamp 现在是 NA 并且新列也是 NA。日期为 NA 和时间为字符 NA
    • 我想知道是否存在某种因素问题。你能edit你的帖子输出dput(taxi_2020[1:20,])吗?实在是太晚了,如果别人帮不了你,我明天再看看。
    • 完成,它太大了。我把谷歌驱动器。绝对是一些格式问题,我也无法在 Python 中阅读它,给我一些字符的错误。谢谢!
    【解决方案2】:

    我们可以使用base R进行拆分

    out <- do.call(rbind.data.frame, strsplit(data[[1]],
            "(?<=[0-9]) (?=[0-9])", perl = TRUE))
    names(out) <- c('Start Date', 'Start Time')
    out
    #  Start Date  Start Time
    #1 12/01/2019 12:30:00 AM
    #2 12/01/2019 12:31:00 AM
    #3 12/01/2019 12:32:00 AM
    

    数据

    data <- structure(list(`Trip Start Timestamp` = c("12/01/2019 12:30:00 AM", 
    "12/01/2019 12:31:00 AM", "12/01/2019 12:32:00 AM")), class = "data.frame", row.names = c(NA, 
    -3L))
    

    【讨论】:

    • 但它给了我数据错误[[1]]:'closure'类型的对象不是子集
    • @Rookie 你能检查一下str(yourdata)。我认为它是data.frametibble,因为它应该适用于这些结构
    • tibble [4,137,294 x 21] (S3: tbl_df/tbl/data.frame) $ 开始日期 : chr [1:4137294] "12/01/2019" "12/01/2019" " 12/01/2019" "12/01/2019" ... $ 开始时间 : chr [1:4137294] "12:15:00 AM" "12:15:00 AM" "12:15:00 AM" "12:15:00 AM" ... $ 结束日期:chr [1:4137294] "12/01/2019" "12/01/2019" "12/01/2019" "12/01/2019" 。 .. $ 结束时间 : chr [1:4137294] "12:30:00 AM" "12:15:00 AM" "12:30:00 AM" "12:30:00 AM" ...
    • @Rookie 你在“开始时间”分开吗?在这种情况下使用strsplit(data[["Start Time"]], ...
    • @Rookie 根据图片,“行程结束时间戳”是第 3 列。所以,你可能需要strsplit(taxi_2020_test[["Trip End Timestamp"]], ...
    【解决方案3】:

    请注意,将输出保持为您显示的格式会将列作为字符/因子返回。

    您可以使用tidyr::separate在空白处拆分数据

    tidyr::separate(data, `Trip Start Timestamp`, c('Start Date', 'Start Time'), 
                           sep = ' ', extra = 'merge')
    
    #  Start Date  Start Time
    #1 12/01/2019 12:30:00 AM
    #2 12/01/2019 12:31:00 AM
    #3 12/01/2019 12:32:00 AM
    

    同样,你可以使用extract

    tidyr::extract(data, `Trip Start Timestamp`, c('Start Date', 'Start Time'), 
                   regex = '(.*?)\\s(.*)')
    

    【讨论】:

    • 但是第一个代码返回列作为字符将所有 NA。知道为什么吗?
    • @Rookie 你的数据肯定不一样。我正在使用伊恩的数据。你能在这些数据上进行测试吗?
    • 不幸的是,它不起作用。错误:列 Time 的长度必须为 4137294(行数)或 1,而不是 3
    • @Rookie 在你的 dput 我认为相关部分只有 structure(list(`Trip Start Timestamp` = c("12/01/2019 12:15:00 AM", "12/01/2019 12:15:00 AM", "12/01/2019 12:15:00 AM"), `Trip End Timestamp` = c("12/01/2019 12:30:00 AM", "12/01/2019 12:15:00 AM", "12/01/2019 12:30:00 AM")), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame")) 。其余的都没有被捡起来吗?对于这些数据,我的答案对我来说很好。
    • @Rookie 我的回答仍然适用于我的更新数据。它对你有用吗?
    【解决方案4】:

    tidyverse

    dat %>%
      mutate(
        ## option 1
        psx = as.POSIXct(V1, format = "%m/%d/%Y %I:%M:%S %p", tz = "UTC"), 
        Date = format(psx, format = "%m/%d/%Y"), 
        Time = format(psx, format = "%I:%M:%S %p"), 
        ## option 2
        Date2 = sub("\\s.*", "", V1), 
        Time2 = sub("^\\S*\\s", "", V1)
      )
    #                        V1                 psx       Date        Time      Date2        Time2
    # 1  12/01/2019 12:30:00 AM 2019-12-01 12:30:00 12/01/2019 12:30:00 PM 12/01/2019  12:30:00 AM
    # 2  12/01/2019 12:31:00 AM 2019-12-01 12:31:00 12/01/2019 12:31:00 PM 12/01/2019  12:31:00 AM
    # 3 12/01/2019 12:32:00 AM  2019-12-01 12:32:00 12/01/2019 12:32:00 PM 12/01/2019 12:32:00 AM 
    

    数据

    dat <- read.table(header = FALSE, text = "
    12/01/2019 12:30:00 AM
    12/01/2019 12:31:00 AM
    12/01/2019 12:32:00 AM ", sep = "|")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-14
      • 2019-02-20
      • 2013-10-18
      • 2018-08-28
      • 2021-11-08
      • 1970-01-01
      • 2021-10-10
      相关资源
      最近更新 更多