【问题标题】:Split date-time column into Date and time variables将日期时间列拆分为日期和时间变量
【发布时间】:2013-10-18 00:24:02
【问题描述】:

我有一个格式为“Y-m-d H:M:S”的“日期时间列“开始”。我想将此列拆分为“日期”和“时间”列。

我尝试了以下方法:

df$Date <- sapply(strsplit(as.character(df$Start), " "), "[", 1)
df$Time <- sapply(strsplit(as.character(df$Start), " "), "[", 2)

但是,如果我使用函数 str(df),这可以工作

# 'data.frame':   18363 obs. of  19 variables:<br>
#  $ Start    : Factor w/ 67 levels "2013-09-01 08:07:41.000",..: 1 1 1 1 1 1 1 1 1 1 ...
# [snip]

所以现在我只需要知道如何将时间和日期从factor 转换为“时间”和“日期”。

【问题讨论】:

  • 使用sapply 而不是lapply。当sapply 遇到“常规”结果时,它会返回一个向量或矩阵。 lapply 总是重新运行一个列表。
  • 就是这样!非常感谢!

标签: r date datetime split


【解决方案1】:

怎么样

df$Date <- as.Date(df$Start)

df$Time <- format(df$Start,"%H:%M:%S")

【讨论】:

  • 这给了我这个错误..:格式错误(结构(as.character(x),名称=名称(x),暗淡=暗淡(x),:无效的'trim'论据
  • 您的 df$Start 类型为“字符”,它不是时间戳。使用 class() 函数进行检查。在应用上述函数之前,您应该将字符串转换为时间戳。
  • 谢谢,R 将其视为一个因素。我已经有一个日期列,实际上确实将“日期”作为一个类。然而,现在我正在与时间作斗争。我用过: df$time
  • strptime(as.character(df$Start),"%Y-%m-%d %H:%M:%S")?
  • 试过那个,但现在它给了我一个错误,“参数'格式'丢失,没有默认值”..
【解决方案2】:
df$Date <- as.Date(df$Start) # already got this one from the answers above
df$Time <- format(as.POSIXct(df$Start), format = "%H:%M:%S") 

使用as.Date 将“开始”转换为Date 类的变量。对于时间变量,我们首先将“开始”转换为POSIXct。然后使用format将时间分量提取为字符串。

【讨论】:

    【解决方案3】:

    通过查看您的列格式,我想说您可以使用 as.POSIXct 正确格式化您的列,然后使用 format() 提取所需的数据。

    这是我在拆分 DateTime 列时使用的代码,

    df$Time <- format(as.POSIXct(df$Start,format="%Y:%m:%d %H:%M:%S"),"%H:%M:%S")
    
    df$Date <- format(as.POSIXct(df$Start,format="%Y:%m:%d %H:%M:%S"),"%Y:%m:%d")
    

    【讨论】:

      【解决方案4】:

      假设您的数据与此类似,有一个 datetime 列和许多其他列

      df <- data.frame(a = 1:5, datetime = as.POSIXct(c('2019-02-01 01:00:00', 
                       '2019-02-01 02:00:00', '2019-02-01 03:00:00', 
                       '2019-02-01 04:00:00', '2019-02-01 05:00:00')))
      
      df
      #  a            datetime
      #1 1 2019-02-01 01:00:00
      #2 2 2019-02-01 02:00:00
      #3 3 2019-02-01 03:00:00
      #4 4 2019-02-01 04:00:00
      #5 5 2019-02-01 05:00:00
      

      我们可以在空格(或任何其他分隔符)上拆分列以获得单独的日期和时间列,这可以使用 tidyr::separate 完成

      tidyr::separate(df, datetime, c("date", "time"), sep = " ")
      #  a       date     time
      #1 1 2019-02-01 01:00:00
      #2 2 2019-02-01 02:00:00
      #3 3 2019-02-01 03:00:00
      #4 4 2019-02-01 04:00:00
      #5 5 2019-02-01 05:00:00
      

      如果我们想保留原始列 (datetime),我们可以添加 remove = FALSE

      【讨论】:

        【解决方案5】:

        您可能更愿意做这样的事情,避免使用lapply 循环,这并不是真正必要的(但这也不是一件坏事!)...

        #  If we had this data...
        df <- data.frame( Start = c( "13:11:2013 15:39" , "13:11:2013 16:15" , "13:11:2013 17:52" ) )
        
        #  We can directly make two columns from the split strings without
        #  using a loop by call 'do.call'..
        new <- do.call( rbind , strsplit( as.character( df$Start ) , " " ) )
        #     [,1]         [,2]   
        #[1,] "13:11:2013" "15:39"
        #[2,] "13:11:2013" "16:15"
        #[3,] "13:11:2013" "17:52"
        
        
        #  Cbind them to the original data liek so...
        cbind( df , Date = new[,2] , Time = new[,1] )
        #             Start  Date       Time
        #1 13:11:2013 15:39 15:39 13:11:2013
        #2 13:11:2013 16:15 16:15 13:11:2013
        #3 13:11:2013 17:52 17:52 13:11:2013
        

        【讨论】:

        • 这似乎不起作用,但这可能是由于 R 将它作为一个因素读入的事实......谢谢!
        • @JalouHuntjens as.character 应该注意这一点。我的示例中的数据也是factor。您可以将str( df ) 添加到 OP 中,以便我查看它的外观吗?
        • @JalouHuntjens 您在数据上运行我的代码时遇到的错误是什么?它应该工作。
        • 它只是给了我一个包含以下内容的列表:5259 48.88 1 13740310 2013-09-04 08:14:11.000。如果我使用 str() 那么它仍然会将它作为一个因素读取,它也不会拆分行。我不知道我做错了什么。无论如何,非常感谢您的帮助!
        【解决方案6】:

        如果您对非base 的替代方案持开放态度,您可以使用data.table::IDateTime which

        接受日期时间输入并返回包含日期和时间列的数据表

        ...分别属于IDate* 和ITime** 类:

        x = as.POSIXct("2013-09-01 08:07:41") + 0:2
        IDateTime(x)
        #         idate    itime
        # 1: 2013-09-01 08:07:41
        # 2: 2013-09-01 08:07:42
        # 3: 2013-09-01 08:07:43
        

        *IDate 是从Date 派生的日期类。它与Date类具有相同的内部表示,除了存储模式是整数。

        **ITime 是一个时间类,存储为一天中的整数秒数。

        【讨论】:

          【解决方案7】:

          您可以在此方法中使用它。效果很好

          format(mdy(df_5star$Date4)
          

          希望对你有帮助!

          【讨论】:

          • 这可能是一个很好的答案。该问题要求创建日期列和时间列,但此答案仅创建一个。此外,您缺少),并且在使用未包含在基础 R 中的函数时(例如mdy()),您应该提及所需的包(大概是lubridate)。
          猜你喜欢
          • 1970-01-01
          • 2021-11-08
          • 2018-08-28
          • 2022-06-14
          • 2019-02-20
          • 1970-01-01
          • 1970-01-01
          • 2018-01-14
          • 1970-01-01
          相关资源
          最近更新 更多