将日期时间列拆分为日期和时间变量

Posted

技术标签:

【中文标题】将日期时间列拆分为日期和时间变量【英文标题】: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 总是重新运行一个列表。 就是这样!非常感谢! 【参考方案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)。

以上是关于将日期时间列拆分为日期和时间变量的主要内容,如果未能解决你的问题,请参考以下文章

(Oracle) SQL 中的正则表达式将日期/时间拆分为单独的日期和时间列

在python中将日期时间拆分为年和月列

如何将包含日期时间的 DataFrame 列拆分为两列:一列包含日期,另一列包含一天中的时间?

Pandas - 根据日期将数据框拆分为多个数据框?

Matlab中tabel如何按照日期列拆分

如何使用python从csv中的同一列拆分日期和时间?