2013-03-09 84 views
4

我有一個Date,並有興趣將其表示爲一個整數yyyymm窗體。目前,我這樣做:R轉換日期到月份表示

get_year_month <- function(d) { return(as.integer(format(d, "%Y%m")))} 
mydate = seq.Date(from=as.Date("2012-01-01"), to=as.Date("5012-01-01"), by=1) 
system.time(ym <- get_year_month(mydate)) 
# user system elapsed 
# 5.972 0.974 6.951 

這對於大型數據集來說非常慢。有更快的方法嗎?請爲您的答案提供時間表,以便輕鬆比較。使用上面的例子。

回答

5

lubridate包使用的功能幾乎可以快兩倍,你的函數:

mydate = as.Date(rep("2012-01-01",1000)) 
library(lubridate) 
library(microbenchmark) 
microbenchmark(get_year_month(mydate), 
       year(mydate)*100+month(mydate)) 

給出:

R> Unit: milliseconds 
           expr  min  lq median  uq 
      get_year_month(mydate) 2.150296 2.188370 2.218176 2.285973 
year(mydate) * 100 + month(mydate) 1.220016 1.228129 1.239704 1.284568 
+0

太棒了!看起來像'lubridate''月份'和'年份'功能比'base'快得多。使用'base'函數會大大增加時間。 – Alex 2013-03-10 00:16:53

0

有可能不是一個單一的項目更快的方法。但是,通過使用內置複製,可以使對集合進行操作的函數的版本運行得比線性快得多。

function mydate(D) { 
    x <- replicate(dim(D)[0], get_year_month(..) 
    return(x) 
} 
+0

感謝您的回答。我不確定這意味着什麼,不幸的是。你能否提供另外兩個例子。 – Alex 2013-03-10 00:16:16

+0

嗨亞歷克斯,請查看使用內置的「複製」,這將避免循環N次(N是您的數組中的條目數)的懲罰。 – javadba 2013-03-10 01:30:37

+0

'replicate'只是'lapply' ..仍然不知道你的意思。作爲其他人與時間一起舉例說明。這可能會消除一些混亂。 – Alex 2013-03-10 01:33:23

2

這將是最好的,讓您的2012年新POSIXlt格式,如果你想操縱他們這樣的:

> system.time(ym <- get_year_month(mydate)) 
    user system elapsed 
    4.039 0.025 4.079 
> system.time(mydatep <- as.POSIXlt(mydate)) 
    user system elapsed 
    3.576 0.016 3.603 
> system.time(ym <- (1900 + mydatep$year)*100 + (mydatep$mon + 1)) 
    user system elapsed 
    0.010 0.005 0.015 

它仍然是一個快一點,你會得到後續類似的行動自由,在時間條款。

+0

有點不熟悉'POSIXlt',但它看起來不像它提供相同的答案... – Alex 2013-03-09 23:18:43

+1

哎呀,我的壞。更正了我的答案。 '$ year'表示1900年後的年數,'$ mon'表示1月後的月數。詳細信息'?POSIXlt'。 – 2013-03-09 23:56:26

2

您可以嘗試使用zoo包中的yearmon類。一般來說,如果您正在進行時間序列操作和分析,我會建議使用xts或至少zoo類。 xts有很多功能用於分析非常巨大的時間序列數據。

以下是針對其他建議解決方案的快速基準。

get_year_month <- function(d) { 
    return(as.integer(format(d, "%Y%m"))) 
} 
mydate = as.Date(rep("2012-01-01", 1e+06)) 

microbenchmark(get_year_month(mydate), year(mydate) * 100 + month(mydate), as.yearmon(mydate, format = "%Y-%m-%d"), times = 1) 
## Unit: milliseconds 
##          expr  min  lq median  uq  max neval 
##     get_year_month(mydate) 1049.8813 1049.8813 1049.8813 1049.8813 1049.8813  1 
##  year(mydate) * 100 + month(mydate) 434.1765 434.1765 434.1765 434.1765 434.1765  1 
## as.yearmon(mydate, format = "%Y-%m-%d") 249.6704 249.6704 249.6704 249.6704 249.6704  1 
+0

(+1)承諾:) – Arun 2013-03-11 09:00:29

相關問題