2017-07-28 123 views
0

我使用此代码以两个POSIXct日期的小时数获得差异。计算POSIXct列的日期差异(BUG?)

x <- transform(x, HRS = ceiling(as.numeric(SHIP_DATE-PICK_DATE))) 

这给出了准确的结果。然而,当我试图找到另一个类似的柱小时的差别,我需要做的是:

x <- transform(x, HRS_ADJ = ceiling(as.numeric(SHIP_DATE-ADJ_PICK_DATE)/60)) 

PICK_DATE & SHIP_DATE使用相同的公式中提取。

x$SHIP_DATE <- ifelse(is.na(as.POSIXct(x$SHIP_DATE, format="%d-%b-%Y %H:%M %p")), 
         yes = as.POSIXct(x$SHIP_DATE, format="%d-%b-%Y %H:%M"), 
         no = as.POSIXct(x$SHIP_DATE, format="%d-%b-%Y %H:%M %p")) 
x$SHIP_DATE <- as.POSIXct(x$SHIP_DATE, origin = "1970-01-01") 

ADJ_PICK_DATE被计算为如下:

x$ADJ_PICK_DATE <- ifelse(x$PICK_TIME=="EARLY", 
          as.POSIXct(paste(format(x$PICK_DATE, "%d-%b-%Y"), "03:00"), 
            format="%d-%b-%Y %H:%M"), x$PICK_DATE) 
x$ADJ_PICK_DATE <- ifelse(x$PICK_TIME=="LATE", 
          as.POSIXct(paste(format(x$PICK_DATE+86400, "%d-%b-%Y"), 
              "03:00"), format="%d-%b-%Y %H:%M"), 
          x$ADJ_PICK_DATE) 
x$ADJ_PICK_DATE <- as.POSIXct(x$ADJ_PICK_DATE, origin = "1970-01-01") 

PICK_TIME被计算以调整PICK_DATE,作为任何订单16:00 & 03:00之间,引线时间将从3AM计算。

问题:

  1. 如何高效地产生ADJ_PICK_DATE柱(现在实在是太 慢)?
  2. 如何使用更短,更高效的代码将源数据提取到POSIXct中? (在我的第7代G​​en CPU上,每百万个数据点需要大约10-15秒)
  3. 为什么我需要对每对日期使用不同的公式来计算天数?

样本数据(的日期在源(PICK_DATE & SHIP_DATE)随机格式化为两个 “DD-MMM-YYYY HH:MM” 和 “DD-MMM-YYYY HH:MM AM/PM”):

PICK_DATE SHIP_DATE PICK_TIME 
01-APR-2017 00:51 02-APR-2017 06:55 EARLY 
01-APR-2017 00:51 02-APR-2017 12:11 PM EARLY 
01-APR-2017 07:51 02-APR-2017 12:11 PM OKAY 
01-APR-2017 02:51 PM 02-APR-2017 09:39 AM LATE 
+0

与其分享大量运行于我们没有的数据的代码,而是共享(使用'dput()')仅仅2或3行数据来说明问题。我认为你的问题可以缩减为一个简短的段落,也可能是10行代码 - 更简短的问题更有可能获得快速的帮助。 [查看更多技巧,在R中提供可重现的示例](https://stackoverflow.com/q/5963269/903061)。 – Gregor

+0

谢谢你,我编辑缩短了查询并消除冗余代码示例。我想我需要包含提取代码,因为这可能是这个奇怪的“错误”的原因。如果我不知道它的来源,那么数据不能被缩放和重用。 – Arani

回答

0

好的,我现在得到了一些解决方案。

  1. 使用lubridate包,这个方法需要大约50%的处理时间:
x$ADJ_PICK_DATE <- ifelse(x$PICK_TIME=="EARLY", 
            dmy_hm(paste(format(x$PICK_DATE, "%d-%b-%Y"), "03:00")), 
            ifelse(x$PICK_TIME=="LATE", 
             dmy_hm(paste(format(x$PICK_DATE+86400, "%d-%b-%Y"), 
                 "03:00")), x$PICK_DATE)) 
     x$ADJ_PICK_DATE <- as.POSIXct(x$ADJ_PICK_DATE, origin = "1970-01-01") 
  • 再次,使用lubridate
  • x$SHIP_DATE <- lubridate::dmy_hm(x$SHIP_DATE) 
    x$PICK_DATE <- lubridate::dmy_hm(x$PICK_DATE) 
    
    1. 在进行转换时可能会出现一些格式错误。我仍然需要帮助解决这个问题。