2017-07-28 168 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. 在進行轉換時可能會出現一些格式錯誤。我仍然需要幫助解決這個問題。