将日期时间列拆分为日期和时间变量
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 将它作为一个因素读入的事实......谢谢! @JalouHuntjensas.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 中的正则表达式将日期/时间拆分为单独的日期和时间列