从长字符串中提取日期

时间:2015-01-20 12:52:13

标签: r date

我有一个数据框,其日期格式如下:

1:9:Tue Aug 12 2014 19:25:24 GMT+0530 (IST)

我想在三个不同的列中提取三个变量日,日期和时间,并将其添加到数据框

Day as Tue
Date as 12/08/2014
Time as 7:25:24PM

前两个数字没有任何意义。

数据框包含超过700,000行,我希望新列替换现有的行。

4 个答案:

答案 0 :(得分:3)

您应该注意将data.frame的日期时间添加为3个单独的列,因为您的3列不能唯一标识特定的日期时间,因为您没有考虑时区。如果您的所有日期时间都在同一时区,那么这不应该是一个问题。

s <- '1:9:Tue Aug 12 2014 19:25:24 GMT+0530 (IST)'
# If the first two numbers do not mean anything and are always separated by a
# colon, then we can remove them with the following gsub command:
s <- gsub("^[[:digit:]:]+","",s)
# Now we can convert the string to a POSIXlt object, assuming they all follow
# the format of including "GMT" before the signed timezone offset
p <- strptime(s, "%a %b %d %Y %H:%M:%S GMT%z")

即使您的日期时间有不同的时区偏移,上述操作仍然有效。例如:

# these times are the same, just in a different timezone (the second is made up)
s <- c('1:9:Tue Aug 12 2014 19:25:24 GMT+0530 (IST)',
       '9:1:Tue Aug 12 2014 19:55:24 GMT+0600 (WAT)')
s <- gsub("^[[:digit:]:]+","",s)
p <- strptime(s, "%a %b %d %Y %H:%M:%S GMT%z")
# the times are the same
as.POSIXct(p, tz="UTC")
# [1] "2014-08-12 08:55:24 UTC" "2014-08-12 08:55:24 UTC"

将日期时间格式化为您想要的字符串很容易;只需使用?strptime中的格式规范。

data.frame(Day=format(p, "%a"), Date=format(p, "%d/%m/%Y"),
  Time=format(p, "%I:%M:%S%p"), stringsAsFactors=FALSE)

答案 1 :(得分:2)

这是一个艰难的。 R对字符串和日期/时间函数没有最佳支持。但我能够让它与一些黑客一起工作:

str <- '1:9:Tue Aug 12 2014 19:25:24 GMT+0530 (IST)';
fieldsBad <- strsplit(str,':')[[1]];
fields <- c(fieldsBad[1:2],paste0(fieldsBad[3:length(fieldsBad)],collapse=':'));
dt <- strptime(fields[3],'%a %b %d %Y %H:%M:%S');

df <- data.frame();
df[1,'Day'] <- strftime(dt,'%a');
df[1,'Date'] <- strftime(dt,'%d/%m/%Y');
df[1,'Time'] <- gsub('^0','',strftime(dt,'%I:%M:%S%p'));

df;

节目:

  Day       Date      Time
1 Tue 12/08/2014 7:25:24PM

黑客的解释:

  1. 不幸的是,strsplit()函数不允许指定要生成的最大字段数,这与Perl中的(例如)http://perldoc.perl.org/functions/split.html不同,后者具有LIMIT参数,这将是完美的。所以我不得不对#34; over-split&#34;然后将额外的字段再次粘贴到带有paste0()的冒号上。

  2. 此外,strptime()调用忽略了时区信息,但幸运的是仍然可以从输入字符串中解析所有内容。我尝试将时区信息明确地传递给tz=参数,但它不会识别IST或GMT + 0530或我尝试的任何内容。但由于你似乎不需要时区,我们还不错。

  3. 最后,strftime()的格式说明符似乎不允许指定没有前导零的12小时时间,因此我必须使用%I并调用gsub()来删除如果存在,它就会关闭。

答案 2 :(得分:1)

library(lubridate)
library(stringr)

d <- "1:9:Tue Aug 12 2014 19:25:24 GMT+0530 (IST)"
d <- gsub("^[[:alnum:]:]+ ", "", d)
tz <- gsub("[ +-]", "", str_extract(d, " ([[:upper:]]+)[+-]"))

strptime(d, "%b %d %Y %H:%M:%S", tz=tz)
## [1] "Aug 12 2014 19:25:24 GMT+0530 (IST)"

由于mapplystrptime采用原子向量,因此您需要tz在数据框上下文中dat$parsed <- mapply(as.POSIXct, gsub("^[[:alnum:]:]+ ", "", dat$date), format="%b %d %Y %H:%M:%S", tz=gsub("[ +-]", "", str_extract(dat$date, " ([[:upper:]]+)[+-]"))) 。所以,做一些像:

dat$parsed

(这会使POSIXct成为数字,但{{1}}将其转换为什么,因此很容易使用)

答案 3 :(得分:-1)

我真的不知道如何在R中做到这一点,但是如果你从js那里得到这个字符串,你可以这样做:

var date = new Date('Tue Aug 12 2014 19:25:24 GMT+0530 (IST)');
console.log(date.getTime());
console.log(date.getTimezoneOffset());

get time方法将以ms为单位返回unix时间戳,getTimezoneOffset将以分钟为单位返回时区偏移量。然后,你可以使用R中的日期函数来解析它。我希望它在那里实现。