【问题标题】:split date and time in different columns of dataframe in R在R中数据框的不同列中拆分日期和时间
【发布时间】:2017-06-02 04:23:16
【问题描述】:

我在 R 中有以下数据框

ID       Date1              Date2       

1        21-03-16 8:36      22-03-16 12:36
1        23-03-16 9:36      24-03-16 01:36
1        22-03-16 10:36     25-03-16 11:46
1        23-03-16 11:36     28-03-16 10:16

我想要的数据框是

ID    Date1        Date1_time    Date2          Date2_time
1     2016-03-21   08:36:00      2016-03-22     12:36:00
1     2016-03-23   09:36:00      2016-03-24     01:36:00
1     2016-03-22   10:36:00      2016-03-25     11:46:00
1     2016-03-23   11:36:00      2016-03-28     10:16:00

我可以使用strptime 单独执行此操作,如下所示

df$Date1 <- strptime(df$Date1, format='%d-%m-%y %H:%M')
df$Date1_time <-  strftime(df$Date1 ,format="%H:%M:%S")
df$Date1 <- strptime(df$Date1, format='%Y-%m-%d')

但是,我有很多日期列可以像上面那样转换。如何在 R 中编写函数来执行此操作。

【问题讨论】:

    标签: r


    【解决方案1】:

    您可以使用dplyr::mutate_at 对多个列进行操作。请参阅select helpers,了解有关有效指定要操作的列的更多信息。

    然后您可以使用lubridatehms 作为日期和时间函数。

    library(dplyr)
    library(lubridate)
    library(hms)
    
    
    df <- readr::read_csv(
    'ID,Date1,Date2
    1,"21-03-16 8:36","22-03-16 12:36"
    1,"23-03-16 9:36","24-03-16 01:36"
    1,"22-03-16 10:36","25-03-16 11:46"
    1,"23-03-16 11:36","28-03-16 10:16"'
    )
    
    df
    
    #> # A tibble: 4 x 3
    #>      ID          Date1          Date2
    #>   <int>          <chr>          <chr>
    #> 1     1  21-03-16 8:36 22-03-16 12:36
    #> 2     1  23-03-16 9:36 24-03-16 01:36
    #> 3     1 22-03-16 10:36 25-03-16 11:46
    #> 4     1 23-03-16 11:36 28-03-16 10:16
    
    df %>% 
      mutate_at(vars(Date1, Date2), dmy_hm) %>% 
      mutate_at(vars(Date1, Date2), funs("date" = date(.), "time" = as.hms(.))) %>% 
      select(-Date1, -Date2)
    
    #> # A tibble: 4 x 5
    #>      ID Date1_date Date2_date Date1_time Date2_time
    #>   <int>     <date>     <date>     <time>     <time>
    #> 1     1 2016-03-21 2016-03-22   08:36:00   12:36:00
    #> 2     1 2016-03-23 2016-03-24   09:36:00   01:36:00
    #> 3     1 2016-03-22 2016-03-25   10:36:00   11:46:00
    #> 4     1 2016-03-23 2016-03-28   11:36:00   10:16:00
    

    【讨论】:

    • 当我运行你的代码时,它会给我Error in as.fun_list(.funs, .env = parent.frame(), ...) : object 'as_datetime' not found
    • 你先运行library(lubridate)了吗?
    • 我用as_date 替换了它,但它给了我一些奇怪的格式日期0021-03-16 和时间00:00:00
    • 嘿,对不起,我完全错过了它是 dmy 而不是 ymd 格式。我已将第一个函数从 as_datetime() 更改为 dmy_hm(),现在它可以工作了
    【解决方案2】:

    使用dplyr 进行操作:

    convertTime <- function(x)as.POSIXct(x, format='%d-%m-%y %H:%M')
    
    df %>% 
        mutate_at(vars(Date1, Date2), convertTime) %>% 
        group_by(ID) %>% 
        mutate_all(funs("date"=as.Date(.), "time"=format(., "%H:%M:%S")))
    
    
    # Source: local data frame [4 x 7]
    # Groups: ID [1]
    # 
    #      ID               Date1               Date2 Date1_date Date2_date Date1_time Date2_time
    #   <int>              <dttm>              <dttm>     <date>     <date>      <chr>      <chr>
    # 1     1 2016-03-22 12:36:00 2016-03-22 12:36:00 2016-03-22 2016-03-22   12:36:00   12:36:00
    # 2     1 2016-03-24 01:36:00 2016-03-24 01:36:00 2016-03-23 2016-03-23   01:36:00   01:36:00
    # 3     1 2016-03-25 11:46:00 2016-03-25 11:46:00 2016-03-25 2016-03-25   11:46:00   11:46:00
    # 4     1 2016-03-28 10:16:00 2016-03-28 10:16:00 2016-03-28 2016-03-28   10:16:00   10:16:00
    

    【讨论】:

    • 通过运行上面的代码,它给了我以下错误Error in mutate_impl(.data, dots) : character string is not in a standard unambiguous format我不想按 ID 分组。希望它为每一行运行
    • 不用担心group_by。在这种情况下,它不会影响 mutate,它被用作绕过标识符变量的一种方式,因此您不需要使用 mutate_all 函数指定所有变量(例如 Date1DateX)。至于错误,你能分享一下你的data.frame的数据结构是什么吗?
    • 这里是 something 与您遇到的错误相关联。最后一行,如果把"date"=as.Date(.)换成"date"=format(., "%Y-%m-%d"),还会报错吗?
    • 它给了Error in mutate_impl(.data, dots) : invalid 'trim' argument
    • 我怀疑你的整个数据集的格式存在一些问题,我怀疑我只能用上面的示例数据进一步帮助你。
    【解决方案3】:

    我有同样的问题,你可以试试这可能对使用 strsplit

    有帮助
    x <- df$Date1    
    y = t(as.data.frame(strsplit(as.character(x),' ')))
        row.names(y) = NULL
    
        # store splitted data into new columns 
        df$date <- y[,1] # date column
        df$time <- y[,2] # time column
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-28
      • 1970-01-01
      • 2016-09-13
      • 1970-01-01
      • 2013-05-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多