R學習 第八篇:日期和時間


R語言的基礎包中提供了三種基本類型用於處理日期和時間,Date用於處理日期,它不包括時間和時區信息;POSIXct/POSIXlt用於處理日期和時間,其中包括了日期、時間和時區信息。R內部在存儲日期和時間時,使用不同的方式:

  • Date類:存儲了從1970年1月1日以來開始計算的天數,更早的日期表示為負值,也就是說,Date類型是一個整數,以天為單位來計算日期,因此,Date適合用於計算日期。
  • POSIXct類:記錄了以時間標准時間(UTC)時區位准的,從1970年1月1日開始計時的秒數,即,POSIXct類型是整數,以秒為單位來計算時間,因此,POSIXct最適合用於存儲和計算時間。
  • POSIXlt類:把日期和時間存儲為一個列表,其中包括秒、分、時和月份等,POSIXlt是使用列表來表示日期和時間,因此,POSIXlt最適合用於提取日期中的特定部分。

一般來講,R語言中創建的時間數據是通過字符型轉化而來,字符串和時間類型無法隱式轉換,必須通過相應的函數來類解析文本。

一,系統當前的日期和時間

在編程中,為了獲得當前的日期和時間,有兩個常用的函數,這兩個函數以Sys開頭,返回的時間受到操作系統區域設置的影響,因此,返回的時間采用本地格式,符合本地的閱讀習慣:

> Sys.Date()
[1] "2018-05-07"
> Sys.time()
[1] "2018-05-07 22:11:45 CST"

R還有一個函數date(),用於返回當前時間對應的文本,只不過格式比較奇葩:

> date()
[1] "Tue May 08 11:32:52 2018"

二,把文本解析成日期和時間

日期值通常以文本的形式輸入到R中,然后轉化為以數值形式存儲的日期變量。而日期需要轉換為文本,才方便讀取。

1, as.Date() 把文本轉換為日期

函數 as.Date()用於把文本轉換為Date類型:

as.Date(x, format)

format參數用於指定輸入的格式,常用的日期格式符號是:

  • %y:兩位數字表示的年份(00-99),不帶世紀,例如,數值是18,格式%y,表示2018年 
  • %Y:四位數字表示的年份(0000-9999)
  • %m:兩位數字的月份,取值范圍是01-12,或1-12
  • %d:月份中的天,取值范圍是01-31
  • %e:月份中的天,取值范圍是1-31
  • %b:縮寫的月份(Jan、Feb、Mar等)
  • %B:英語月份全名(January、February 、March等)
  • %a:縮寫的星期名(Mon、Tue、Wed、Thur、Fri、Sat、Sun)
  • %A:星期全名

例如,把一個向量中的字符元素轉換為日期類型:

as.Date(c('2018-05-01','2018-05-05'),'%Y-%m-%d')

2,strptime() 解析日期

函數strptime(),是string parse time的簡稱,返回POSIXlt日期。在解析日期時,必須指定文本和日期對應的位置,日期的格式使用%+字母來指定。

format(x, format = "", tz = "")

參數tz是時區(time zone),默認值是空,在解析時,如果不指定時區,R會調用Sys.timezone

日期格式和format()函數相同,常用的時間格式符號是:

  • %H:小時(24小時制)
  • %I:小時(12小時制)
  • %p:對於12小時制,指定上午(AM)或下午(PM)
  • %M:分鍾
  • %S:秒

例如,把date()函數返回的文本解析成時間類型:

> nowstr <- date()
> nowtime <- strptime(nowstr,'%a %b %d %H:%M:%S %Y')
> print(nowtime)
[1] "2018-05-08 13:01:04 CST"

三,把日期和時間格式化為文本

把日期和時間格式化成文本,便於閱讀

1,format() 把日期轉換為文本

對日期進行格式化,轉換為可讀的文本,format()函數的定義是:

format(x, format = "", tz = "")

x是日期參數,format是輸出的格式,tz是時區,該函數按照指定的格式輸出文本:

today <- Sys.Date()
mydate <- format(today,format='%Y-%m-%d')

2,strftime()格式化日期

函數strftime(),是string formated time的簡稱,用於把時間轉換為字符串,

strptime(x, format, tz = "")

該函數和format()函數的功能和使用方式幾乎完全相同。

today <- Sys.Date()
mydate <- strftime(today,format='%Y-%m-%d')

四,日期的比較

由於POSIXct類是以秒為單位來計算時間,Date類是以天為單位類計算日期,這意味着可以在日期值上執行比較運算和算術運算:

  • 將數字和Date類相加,增加或減少相應的天數
  • 將數字和POSIXct類相加,增加或減少相應的秒數

1,時間和數字相加

時間以秒為單位:

> time1 <- Sys.time()
> print(time1)
[1] "2018-05-08 13:16:36 CST"
> print(time1+60*60)
[1] "2018-05-08 14:16:36 CST"

日期以天為單位:

> date1 <- Sys.Date()
> print(date1)
[1] "2018-05-08"
> print(date1+1)
[1] "2018-05-09"

2,時間比較

由於Date類和POSIXct類實際上都是一個整數,可以直接比較大小

date1 <- as.Date('2018-01-01')
date2 <- as.Date('2018-02-01')
if (date2>date1) print ('gt')

五,lubridate包介紹

lubridate包使得日期和時間的處理更加規范,簡單和靈活。lubridate中所有解析函數都會返回POSIXct日期,默認都是用UTC時區。

lubridate包主要有兩類函數,一類是處理時點數據(time instants),另一類是處理時段數據(time spans)。

安裝和載入lubridate包:

install.packages("lubridate")
library(lubridate)

系統的當前時間now(),和Sys.time()函數返回的時間相同;系統的當前日期today(),和Sys.Date()函數返回的日期相同:

now(tzone = "")
today(tzone = "")

1,從字符串轉換為日期類型

ymd() 函數用於從字符型數據解析時間,該函數會自動識別各種分隔符,函數的定義是:

ymd(..., quiet = FALSE, tz = NULL)

參數注釋:

  • quiet:布爾值,當指定為TRUE時,移除文本中自定義的文本
  • tz:時區,默認值是NULL

基本用法如下:

x <- ymd('2010-04-08')

而ymd代表文本的格式必須依次是:year、month、day,除了ymd之外,還有ydm、mdy、myd、dmy、dym。

2,從字符類型轉換為時間類型

ymd_hms()函數用於把文本解析為時間,該函數會自動識別各種分隔符

ymd_hms(..., quiet = FALSE, tz = "UTC")

3,抽取或設置時間的部分

  • date:抽取或設置時間的日期
  • year
  • month
  • day
  • week
  • hour
  • minute
  • second

例如,抽取當前時間的月份:

> month(t<-now())
[1] 5

例如,設置當前時間的月份為6月:

x< now()
month(x) <- 6

4,時間間隔(Intervals)

時間間隔是由開始時間和結束時間構成的對象,本身用途不大,最常用於指定期間和周期:

auckland <- interval(arrive, leave) 
auckland
#> [1] 2011-06-04 12:00:00 NZST--2011-08-10 14:00:00 NZST
auckland <- arrive %--% leave
auckland
#> [1] 2011-06-04 12:00:00 NZST--2011-08-10 14:00:00 NZST

5,時間的運算

lubridata還能創建兩類對象:期間(Duration)和周期(Period),創建period的輔助函數是unit+s,創建duration的輔助函數是d+unit+s,unit是時間單位,常用的時間單位有:year、month、week、day、hour、minute和second。期間指定的時間跨度位秒的倍數,是固定的秒數。例如,一天的總時間是86 400秒(60 x 60 x 24),一年的總時間是86 400 x 365 (秒),期間類型把一年的天數固定位365天,沒有考慮閏年。周期period根據日歷來指定時間闊度,這意味着,在把周期添加到一個時間之前,period的確切的時間跨度是不固定的。例如,一年的周期可以是365天,也可以是366天,這取決於它是否是閏年。時間和日期的算術運算,跟期間和周期有關系,經常用到的是周期period類型。

常用的duration類的函數有:

duration(num = NULL, units = "seconds", ...)
is.duration(x)
dseconds(x = 1)
dminutes(x = 1)
dhours(x = 1)
ddays(x = 1)
dweeks(x = 1)
dyears(x = 1)

常用的period類的函數有:

period(num = NULL, units = "second", ...)
is.period(x)
seconds(x = 1)
minutes(x = 1)
hours(x = 1)
days(x = 1)
weeks(x = 1)
years(x = 1)
months(x)

注意,duration類沒有dmonths()函數,可能是因為月份持續的天數十分不固定,無法指定一個固定的總時間(秒)。

例1,2分鍾的period和duration分別是:

minutes(2) ## period
#> [1] "2M 0S"
dminutes(2) ## duration
#> [1] "120s (~2 minutes)"

例2,對時間加上期間和周期,返回的結果是不同的:

> ymd(20120101) + dyears(1)
[1] "2012-12-31"
> ymd(20120101) + years(1)
[1] "2013-01-01"

例3,日期的下一個月:

ymd('2018-01-01')+months(1)

6,日期周期的開始和結束

使用以下兩個函數獲得日期的開始或結束時間:

floor_date(x, unit = "seconds", week_start = getOption("lubridate.week.start", 7))
ceiling_date(x, unit = "seconds", change_on_boundary = NULL, week_start = getOption("lubridate.week.start", 7))

例如,獲得YTD的開始和結束日期:

ytd_start <- floor_date(Sys.Date(),'year')
ytd_end <- floor_date(Sys.Date(),'month')

 

 

參考文檔:

Make Dealing with Dates a Little Easier

Do more with dates and times in R

R語言中的時間與日期

R包實踐:lubridate 處理時間數據

時間處理–lubridata包


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM