R語言中日期和時間處理

    在R基礎包中提供了兩類的時間數據,一類是Date日期數據,不包括時間和時區信息,另外一類是POSIXct/POSIXlt類型數據,其中包括了日期、時間和時區信息。通常來說,R語言中創建時序數據是經過字符型轉化而來,但因爲時序數據形式多樣,並且R中存貯格式也是五花八門,例如Date/ts/xts/zoo/tis/fts等等。總之處理起來也比較麻煩,這篇文章介紹用lubridate包來處理。函數

  • lubridate包

該主要有兩類函數,一類用於處理時點數據(timeinstants),另外一類則用於處理時段數據(time spans)。雖然這些基礎功能R base也能實現,可是操做起來會比較麻煩。一下二者對時間數據處理的對比spa

  • 解析日期與時間(Parsing dates and times)

使用lubridate包識別日期前,咱們須要告訴它年(y)月(m)日(d)的排列順序,而函數本省就是這個幾個字母的組合,.net

> ymd(20170629);myd(06201729);dmy(29062017)
[1] "2017-06-29"
[1] "2017-06-29"
[1] "2017-06-29"

    在此基礎上,若是須要讀取含具體時間的數據,能夠在函數裏再加上小時(h)分鐘(m)和秒(s);若是須要讀入的時間具備特定時區,那就用tz選項來指定code

> test_date <- ymd_hms("2017-06-29-12-01-30", tz = "Pacific/Auckland")
> test_date
[1] "2017-06-29 12:01:30 NZST"

全部公式以下表orm

lubriadate很是靈活,能夠「智能」判斷輸入的格式,最好的獲得標準的時間格式,甚至即便你輸入的不徹底正確blog

> test_date<- c(20170601, "2017-06-02", "2017 06 03", "2017-6-4","2017-6, 5", "Created on 2017 6 6", "201706 !!! 07")
> ymd(test_date)
[1] "2017-06-01" "2017-06-02" "2017-06-03" "2017-06-04" "2017-06-05" "2017-06-06" "2017-06-07"

    在上面的例子中,日期時間數據雖然雜亂,但仍是按照年、月、日的順序排列的,但若是拿到的數據年月日是無序排列的呢?ip

    parse_date_timeci

能夠將格式各樣的日期時間字符轉換爲日期時間類型的數據。該函數中有一個重要的參數,即orders,經過該參數指定可能的日期格式順序,如年-月-日或月-日-年等順序get

> test_date <- c('20131113','120315','12/17/1996','09-01-01','2015 12 23','2009-1, 5','Created on 2013 4 6')
> parse_date_time(test_date,order = c('ymd','mdy','dmy','ymd'))
[1] "2013-11-13 UTC" "2012-03-15 UTC" "1996-12-17 UTC" "2009-01-01 UTC" "2015-12-23 UTC"
[6] "2009-01-05 UTC" "2013-04-06 UTC"

 

  • 設置與提取信息(Setting and Extracting information)

    一、精確提取博客

從日期時間提取信息的函數也很是直觀,second(),minute(),hour(),day(),wday(),yday(),week(),month(),year(),tz()分別能夠提取秒、分、小時、天、周的第幾天,年的第幾天、星期、月、年和時區的信息。這些函數一樣也能夠用來設置修改這些信息。其中,wday()和month()這兩個功能有一個label的選項,能夠選擇顯示數值或者是名字(eg:wday()可顯示7或者Sat。注:weekday默認週日爲1)

> test <- ymd_hms('2017/06/29/12/00/00')
> test
[1] "2017-06-29 12:00:00 UTC"
> second(test) <- 30
> test
[1] "2017-06-29 12:00:30 UTC"

 

> wday(test)
[1] 5
> wday(test,label = TRUE)
[1] Thurs
Levels: Sun < Mon < Tues < Wed < Thurs < Fri < Sat

 

    二、模糊提取(取整)

模糊取整即截斷函數,即將日期時間類型數據取整到不一樣的單位,如年、季、月、日、時等

# 四捨五入取整
> round_date()
# 向下取整
> floor_date()
# 向上取整
> ceiling_date()

 

> test_date <- as.POSIXct("2017-06-29 12:34:59")
> round_date(test_date,'hour')
[1] "2017-06-29 13:00:00 CST"
> ceiling_date(test_date,'hour')
[1] "2017-06-29 13:00:00 CST"
> floor_date(test_date,'hour')
[1] "2017-06-29 12:00:00 CST"

 

# 自定義提取
> x <- as.POSIXct("2017-06-29 12:01:59.23")
> round_date(x, "second")
[1] "2017-06-29 12:01:59 CST"
> round_date(x, "minute")
[1] "2017-06-29 12:02:00 CST"
> round_date(x, "2 hours")
[1] "2017-06-29 12:00:00 CST"
> round_date(x, "halfyear")
[1] "2017-07-01 CST"
> round_date(x, "month")
[1] "2017-07-01 CST"
> round_date(x, "5 mins")
[1] "2017-06-29 12:00:00 CST"
# 向上向下取整同理

 

  • 時區(Time Zones)

在lubridate包中,與時區相關的function主要作兩件事,

其一,顯示同一個時間點在不一樣時區的時間,簡單來說就是變換時區,用with_tz();其二,結合某個時間點與給定時區,新建一個給定時區的時間點,第二個是固定時區,用fore_tz()。

> test_date <- ymd_hms("2017-06-29 09:00:00", tz = "Pacific/Auckland")
> with_tz(test_date,"America/New_York")
[1] "2017-06-28 17:00:00 EDT"

> test_date_1 <- force_tz(test_date,tz="Europe/London")
> test_date_1
[1] "2017-06-29 12:00:00 BST"

 

  • 時間間隔(Time Intervals)
> begin1 <- ymd_hms("20150903,12:00:00")
> end1 <- ymd_hms("20160804,12;30:00")
> begin2 <- ymd_hms("20151203,12:00:00")
> end2 <- ymd_hms("20160904,12;30:00")

> test_date_1 <- interval(begin1,end1) #使用interval()方法,先傳小的開始值,再傳大的結束值
> test_date_1
[1] 2015-09-03 12:00:00 UTC--2016-08-04 12:30:00 UTC
> test_date_2 <- interval(begin2,end2)
# 判斷兩段時間是否有重疊
> int_overlaps(test_date_1,test_date_2)
[1] TRUE

其餘操做時間間隔的函數還包含:int_start,int_end,int_flip,int_shift,int_aligns,union,intersect和%within%等。

在獲得時間間隔的數據後,還能夠經過time_length()函數進一步計算間隔內的不一樣度量單位下的時間:

> time_length(test_date_1,'day')
[1] 336.0208
> time_length(test_date_1,'year')
[1] 0.9180897
> time_length(test_date_1,'month')
[1] 11.03293
> time_length(test_date_1,'seconds')
[1] 29032200

 

  • 日期時間的計算(Arithmetic with date times)

    一、時間跨度(durations和periods)

時間間隔是特定的時間跨度(由於它綁定在特定時間點上)。lubridate同時也提供了通常的時間跨度的類:durations和periods。創建periods的function是用時間單位(複數)來命名的。而創建duration的function命名和periods的一致,僅在前綴加一個‘d'。

# periods
> minutes(1)   
[1] "1M 0S"
# durations[加前綴'd']
> dminutes(1)  
[1] "60s"

爲何要這兩個不一樣的類呢?由於時間線(timeline)並無數字線(number line)那樣可靠。durations類一般提供了更準確的運算結果。一個 duration年老是等於365天 。而periods是隨着時間線的波動而給出更理性的結果,這一特色在創建時鐘時間(clock times)的模型時很是有用。比方說,durations遇到閏年時,仍是365天,而periods給出的結果就靈活不少

> leap_year(2016)
[1] TRUE
> ymd(20160101)+years(1)
[1] "2017-01-01"
> ymd(20160101)+dyears(1)
[1] "2016-12-31"

利用peridos或者durations來作基本的日期運算,例如:得出接下來的六週的一個相同時間點

> test_date <- test_date + weeks(0:5)
> test_date
[1] "2017-06-29 12:00:00 CDT" "2017-07-06 12:00:00 CDT" "2017-07-13 12:00:00 CDT"
[4] "2017-07-20 12:00:00 CDT" "2017-07-27 12:00:00 CDT" "2017-08-03 12:00:00 CDT"

 

> test_date_2 / ddays(1)
[1] 276.0208
> test_date_2 / dminutes(5)
[1] 79494

 

# 取整
> test_date_2 %/% months(1)
[1] 9
# 取餘
> test_date_2 %% months(1)
[1] 2016-09-03 12:00:00 UTC--2016-09-04 12:30:00 UTC

用時間間隔爲模數會獲得一個餘數,它是一個新的時間間隔。能夠用as.period()把這個時間間隔轉變爲period類(非特定時間跨度的類)。

> as.period(test_date_2 %% months(1))
[1] "1d 0H 30M 0S"

    2. %m+%

在時間計算時,因爲日期數據的特殊性,若是咱們須要獲得每月的最後一天的日期數據,直接在某一個月的最後一天上加上月份很明顯是錯誤的。爲此咱們引入%m+%函數:

> test_date_0 <- as.Date('2015-01-31')
> test_date_2 <- test_date_0 %m+% months(0:11)
> test_date_2
 [1] "2015-01-31" "2015-02-28" "2015-03-31" "2015-04-30" "2015-05-31" "2015-06-30"
 [7] "2015-07-31" "2015-08-31" "2015-09-30" "2015-10-31" "2015-11-30" "2015-12-31"

整理來自

[1] Learn R | 日期時間處理之lubridate包

[2] R語言與格式、日期格式、格式轉化 - CSDN博客

[3] R語言時間處理函數 - CSDN博客

[4] Learn R | 日期時間處理之lubridate包

相關文章
相關標籤/搜索