R 从长字符串中提取日期

R 从长字符串中提取日期,r,date,R,Date,我有一个数据框,其中日期格式如下: 1:9:Tue Aug 12 2014 19:25:24 GMT+0530 (IST) 我想在三个不同的列中提取三个变量day、date和time,并将其添加到数据框中 Day as Tue Date as 12/08/2014 Time as 7:25:24PM 前两个数字没有任何意义 dataframe由700000多行组成,我想用新列替换现有列。我真的不知道如何在R中实现,但是如果你从js获得这个字符串,你可以这样做: var date = new

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

1:9:Tue Aug 12 2014 19:25:24 GMT+0530 (IST)
我想在三个不同的列中提取三个变量day、date和time,并将其添加到数据框中

Day as Tue
Date as 12/08/2014
Time as 7:25:24PM
前两个数字没有任何意义


dataframe由700000多行组成,我想用新列替换现有列。

我真的不知道如何在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方法将以毫秒为单位返回unix时间戳,getTimezoneOffset将以分钟为单位返回时区偏移量。然后,您可以使用R中的日期函数来解析它。我希望它在那里实现。

这是一个困难的问题。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;
黑客解释:

  • 不幸的是,
    strsplit()
    函数不允许指定要生成的字段的最大数量,这与(例如)Perl不同,Perl中有一个
    LIMIT
    参数,在这里非常完美。因此,我必须对“过度拆分”进行排序,然后使用
    paste0()
    将额外字段重新粘贴到冒号上

  • 另外,
    strtime()
    调用会忽略时区信息,不过幸运的是,它仍然可以从输入字符串中解析所有信息。我尝试将时区信息显式传递给
    tz=
    参数,但它无法识别IST或GMT+0530或我尝试的任何东西。但既然你似乎不需要时区,我们就可以了

  • 最后,
    strftime()
    的格式说明符似乎不允许在没有前导零的情况下指定12小时时间,因此我必须使用
    %I
    并调用
    gsub()
    将其删除(如果存在)


  • (这将使
    dat$parsed
    成为数字,但这正是
    POSIXct
    将其转换为的内容,因此易于使用)

    在将datetime作为3个单独的列添加到data.frame时,您应该小心,因为这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")
    

    “R没有对字符串和日期/时间函数的最佳支持。”呃…
    lubridate
    pacakge,mebbe?我从未使用过
    lubridate
    ,看起来是个不错的软件包。很好的建议@hrbrmstrI认为它没有正确解析时间和时区。当我添加对
    console.log(日期)的调用时,我得到
    日期{2014年8月12日星期二09:55:24 GMT-0400(东部夏令时)}
    。这是您所在时区的时间。我想没关系。哦,哈,你说得对。它解析正确,只是在我的时区显示结果(从GMT+0530偏移9.5小时)。那太好了!为您的见解投了赞成票。答案没有日期。你能试着把它也包括在答案中吗?@SuryaPavanPynda:我认为格式化日期时间很简单,所以我没有包括它。我刚刚加了。
    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)"
    
    dat$parsed <- mapply(as.POSIXct, 
           gsub("^[[:alnum:]:]+ ", "", dat$date),
           format="%b %d %Y %H:%M:%S", 
           tz=gsub("[ +-]", "", str_extract(dat$date, " ([[:upper:]]+)[+-]")))
    
    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"
    
    data.frame(Day=format(p, "%a"), Date=format(p, "%d/%m/%Y"),
      Time=format(p, "%I:%M:%S%p"), stringsAsFactors=FALSE)