我有一个数据框,其日期格式如下:
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行,我希望新列替换现有的行。
答案 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
黑客的解释:
不幸的是,strsplit()
函数不允许指定要生成的最大字段数,这与Perl中的(例如)http://perldoc.perl.org/functions/split.html不同,后者具有LIMIT
参数,这将是完美的。所以我不得不对#34; over-split&#34;然后将额外的字段再次粘贴到带有paste0()
的冒号上。
此外,strptime()
调用忽略了时区信息,但幸运的是仍然可以从输入字符串中解析所有内容。我尝试将时区信息明确地传递给tz=
参数,但它不会识别IST或GMT + 0530或我尝试的任何内容。但由于你似乎不需要时区,我们还不错。
最后,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)"
由于mapply
为strptime
采用原子向量,因此您需要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中的日期函数来解析它。我希望它在那里实现。