---
disqus: ahb0222
GA : G-CQ4L16KHK4
---
# R語言_時間資料處理
> [color=#40f1ef][name=LHB阿好伯, Dec 18, 2019 ][:earth_africa:](https://www.facebook.com/LHB0222/)
###### tags: `R`
![](https://i.imgur.com/ruBLLMd.jpg)
在R資料處理之中,時常會需要遇到時間格式的處理
實驗數據、股市資料、氣候資訊隨著時間不斷的流逝
各式資料也不斷的生成的情況下時間的判讀就顯得重要
多數時候取得的時間資料就是一長串的數字
如何讓程式讀取時間資料以及對時間資料的處理是今天這文章的重點
[TOC]
# 取得時間資訊
```R=
Sys.Date() #當前日期 lubridate::today()
date() #當前系統日期和時間
Sys.time() #當前系統日期和時間 lubridate::now()
Sys.timezone() #有關時區的信息將返回當前時區的名稱
```
:::success
[1] "2019-12-13"
[1] "Fri Dec 13 21:50:58 2019"
[1] "2019-12-13 21:52:04 CST"
[1] "Asia/Taipei"
:::
```R=+
head(OlsonNames()) #取得有關時區的信息、時區的名稱
```
:::success
[1] "Africa/Abidjan" "Africa/Accra" "Africa/Addis_Ababa" "Africa/Algiers"
[5] "Africa/Asmara" "Africa/Asmera"
:::
## 取得特定日期或時間資訊
:::danger
format(date,format)
:::
```R=
#輸出年份:
format(Sys.Date(),format="%Y")
format(Sys.Date(),format="%y")
#輸出月份:
format(Sys.Date(),format="%b")
format(Sys.Date(),format="%B")
format(Sys.Date(),format="%m")
#輸出星期:
format(Sys.Date(),format="%A")
format(Sys.Date(),format="%a")
#摻雜文字輸出:
format(Sys.Date(),format="%Y年%m月%d日")
```
:::success
#輸出年份:
[1] "2019"
[1] "17"
[1] "19"
#輸出月份:
[1] "十二月"
[1] "十二月"
[1] "12"
#輸出星期:
[1] "星期五"
[1] "週五"
#摻雜文字輸出:
[1] "2019年12月13日"
:::
也可以使用其他內置函數處理
```R=
weekdays(Sys.Date()) #取得日期物件的星期資料
months(Sys.Date()) #取得日期物件的月份
days(Sys.Date()) #取得日期物件日期
quarters(Sys.Date()) #取得日期物件的季度
```
# 單日期之文字格式轉換
:::danger
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|星期全名|
```R=
as.Date('2019-12-02', '%Y-%m-%d')
as.Date('12/02 2019', '%m/%d %Y')
```
:::success
[1] "2019-12-02"
[1] "2019-12-02"
:::
# 包含時間資料之文字格式轉換
:::danger
as.POSIXlt(x, format)
as.POSIXct(x, format)
:::
**POSIXlt** 是以列表的形式分別儲存年、月、日、时、分、秒資料
**POSIXct** 則是以1970年1月1號開始計算過了幾秒,如果是負數,則是1970-01-01年以前;
正數則是1970年以後。
| %H|小時(24小時制)|
|---|---|
|%I|小時(12小時制)|
|%p|對於12小時制,指定上午(AM)或下午(PM)|
|%M|分鐘|
|%S|秒|
```R=
as.POSIXlt('2019/12/13 22:12:00', format="%Y/%m/%d %H:%M:%S")
as.POSIXct('2019/12/13 22:12:00', format="%Y/%m/%d %H:%M:%S")
```
:::success
[1] "2019-12-13 22:12:00 CST"
[1] "2019-12-13 22:12:00 CST"
:::
比如2019/12/13 22:12:00相比於1970年1月1號經過了1576246320秒
```R=+
unclass(as.POSIXct('2019/12/13 22:12:00', format="%Y/%m/%d %H:%M:%S"))
```
:::success
[1] 1576246320
attr(,"tzone")
[1] ""
:::
```R=+
unclass(as.POSIXlt('2019/12/13 22:12:00', format="%Y/%m/%d %H:%M:%S"))
```
:::success
$sec
[1] 0
$min
[1] 12
$hour
[1] 22
$mday
[1] 13
$mon
[1] 11
$year
[1] 119
$wday
[1] 5
$yday
[1] 346
$isdst
[1] 0
$zone
[1] "CST"
$gmtoff
[1] NA
:::
# 時間格式之運算
不同時間格式間可以進行相減但無法進行相加
```R=
D1 <- as.POSIXlt('2019/12/13 22:12:00', format="%Y/%m/%d %H:%M:%S")
D2 <- as.POSIXlt('2019/12/13 10:12:00', format="%Y/%m/%d %H:%M:%S")
D3 <- as.POSIXct('2019/12/13 22:12:00', format="%Y/%m/%d %H:%M:%S")
D4 <- as.POSIXct('2019/12/13 10:12:00', format="%Y/%m/%d %H:%M:%S")
D1-D2
D1-D3
D1-D4
```
:::success
Time difference of 12 hours
Time difference of 0 secs
Time difference of 12 hours
:::
```R=+
D1+D4
D1+D2
```
:::success
Error in `+.POSIXt`(D1, D4) :
binary '+' is not defined for "POSIXt" objects
Error in `+.POSIXt`(D1, D2) :
binary '+' is not defined for "POSIXt" objects
:::
而加上數字則為秒數增加
`D1 + 1`
[1] "2019-12-13 22:12:01 CST"
`D1 + 60`
[1] "2019-12-13 22:36:00 CST"
`D1 + 60 * 60`
[1] "2019-12-13 23:12:00 CST"
`D1 + 60 * 60 * 24`
[1] "2019-12-14 22:12:00 CST"
`D1 + 60 * 60 * 24 * 30`
[1] "2020-01-12 22:12:00 CST"
時間格式間計算時間差可以使用difftime()
:::danger
difftime(time1, time2, tz,units = c("auto", "secs", "mins", "hours","days", "weeks"))
:::
```R=
D1 <- as.Date("2019/12/16")
D2 <- as.Date("2012/11/17")
difftime(D1, D2, units ="secs")
```
:::success
Time difference of 223344000 secs
:::
# lubridate套件更靈活處理R時間格式
```R=
install.packages("lubridate") #安裝套件
library(lubridate) #讀取套件
```
lubridate主要有判斷、提取、修改等功能
## 判斷日期日期
lubridate以y代表yeard, m代表month, d代表day,透過y-m-d的不同排序來判斷時間格式
```R=+
ymd("2019-12-16")
ymd("2019/12/16")
ymd("2019_12_16")
ymd("19_12_16")
mdy("121619")
dmy(161219)
```
:::success
[1] "2019-12-16"
[1] "2019-12-16"
[1] "2019-12-16"
[1] "2019-12-16"
[1] "2019-12-16"
[1] "2019-12-16"
:::
再搭配h表示小時,m為分鐘與s為秒可以組成dmy_hms、ymd_hms等函數來判斷包含時間之格式
```R=+
ymd_hms("2019_12_16 12:01:56")
ymd_hm("2019_12_16 12:01")
ymd_h("2019_12_16 12")
mdy_hms("121619 12:01:56")
```
:::success
[1] "2019-12-16 12:01:56 UTC"
[1] "2019-12-16 12:01:00 UTC"
[1] "2019-12-16 12:00:00 UTC"
[1] "2019-12-16 12:01:56 UTC"
:::
## 簡單的函數來獲取日期或時間物件
:::danger
year() #取得年份
month() #取得月份
mday() #取的日期
hour() #取得小時數
minute() #取得分鐘數
second() #取得秒數
:::
```R=
D5 <- mdy_hms("121619 12:01:56")
year(D5) #取得年份
month(D5) #取得月份
mday(D5) #取的日期
hour(D5) #取得小時數
minute(D5) #取得分鐘數
second(D5) #取得秒數
```
:::success
[1] 2019
[1] 12
[1] 16
[1] 12
[1] 1
[1] 56
:::
:::danger
yday() #判斷日期為這一年得第幾天
wday() #判斷日期星期
week() #判斷日期為這一年得第幾周
days_in_month() #取得日期當月的最大天數
:::
```R=+
yday(D5) #判斷日期為這一年得第幾天
wday(D5) #判斷日期星期
week(D5) #判斷日期為這一年得第幾周
days_in_month(D5) #取得日期當月的最大天數
```
:::success
[1] 350
[1] 2
[1] 50
Dec
31
:::
## 時間的四捨五入與條件捨去、進位
:::danger
round_date(x, unit) #將時間依據單位四捨五入
floor_date(x, unit) #將時間依據單位條件捨去
ceiling_date(x, unit) #將時間依據單位條件進位
**可使用單位Valid base units are second, minute, hour, day, week, month, bimonth(雙月), quarter(季度), season(季節), halfyear(半年) and year**
:::
```R=+
round_date(D5, unit = "day") #將時間四捨五入至天數
floor_date(D5, unit = "day") #將時間條件捨去至天數
ceiling_date(D5, unit = "day") #將時間條件進位至天數
```
:::success
[1] "2019-12-17 UTC"
[1] "2019-12-16 UTC"
[1] "2019-12-17 UTC"
:::
參考資料
>[lubridate.tidyverse](https://lubridate.tidyverse.org/)
>[Dates and times with lubridate : : CHEAT SHEET(速查表)](https://rawgit.com/rstudio/cheatsheets/master/lubridate.pdf)
>[R for Data Science](https://r4ds.had.co.nz/dates-and-times.html)
[name=Garrett Grolemund、Hadley Wickham]
全文分享至
https://www.facebook.com/LHB0222/
有疑問想討論的都歡迎於下方留言
喜歡的幫我分享給所有的朋友 \o/
有所錯誤歡迎指教
![](https://i.imgur.com/47HlvGH.png)