第 4 章 R Basics

參考資料

4.1 Create an object with values

這章我們學習如何創造R裡帶有資訊的物件,在R裡創造方式為:

ObjectName <- object_value

object_value -> ObjectName
a <- 2

3 -> b

4.2 Calling an object with values

a
`a`

4.3 Numeric

a<-5
a2<-5L
aVector<-c(5,6,7)
a2Vector<-c(5L,6L,7L)

使用class()查詢上述物件類別。

4.4 Character/String (vector)

在定義object value時,必需要用「成對」的"',把每個字串括起來。

b<-"你好"
bVector<-c("你好","How are you?")

使用class()查詢上述物件類別。

若要產生小明說:"明天不用上課。",值的內容有包含",這使可改用成對的'定義值,如:

dialogue <- c('小明說:"明天不用上課。"',
               '小花說:"真的嗎?"')

cat(dialogue, sep="\n")

以上對白請把它改成:

小明說:'明天不用上課。'
小花說:'真的嗎?'

4.5 Logical

邏輯:

  • 為「真」: TTRUE (要全大寫)。

  • 為「否」: FFALSE (要全大寫)。

aLogical <- c(T,TRUE,F,FALSE,FALSE)
class(aLogical)

邏輯值遇到數學運算時T會被當成1,而F會被當成0。

# 加總向量內的所有元素值。
sum(aLogical)

4.6 Factor

參考資料:https://r4ds.had.co.nz/factors.html

R represents categorical data with factors.

  • A factor is an integer vector with a levels attribute.

  • A levels attribute stores a set of mappings between integers and categorical values.

  • When you view a factor, R displays not the integers, but the values associated with them.
studentMajors <- factor(
  c("經濟系", "經濟系", "法律系")
)

R是怎麼儲存studentMajors這個物件:

typeof(studentMajors)

Levels attribute的mapping是什麼:

levels(studentMajors)
  • levels顯示的類別名稱(categorical values)順序整數值即R真正儲存的內容:

    法律系會存成1; 經濟系會存成2

螢幕顯示的studentMajors會是其categorical values:

studentMajors

真正儲存內容可以用as.integer()將其顯示出來:

as.integer(studentMajors)

as.integer(...)會將…物件(嘗試)轉成integer class的物件。例如:

stringInteger <- c("1","2","-11")
class(stringInteger) # 無法進行數值運算

trueInteger <- as.integer(stringInteger)
class(trueInteger) # 可以進行數值運算

R裡頭有很多as.className(...)之類的函數,協助使用者在必要時轉變物件的class。

4.7 Date and Time

參考資料:

  1. RDS: Chapter 16
  2. 使用R處理時間資料(DateTimeClasses)的格式(lubridate, POSIXlt,POSIXlc)

所有程式環境都需要特別去處理時間日期。對人類而言,日期/時間可以以文字呈現,人類也知道時間的連續性(如兩個時點差多少秒、多少小時等)。為了讓機器也可以處理時間,必需要:

  • 將文字日期/時間轉成可做加減等運算的數值

同時又要:

  • 螢幕顯示為人類可理解的時點文字

How computer sees time?

“2019-03-18 15:00:20”是常見的人類文字日期時間(date time)寫法,我們會說它是“YYYY-MM-DD HH:MM:SS”寫法。

考慮另一個date time: “2019-03-18 15:01:23”——這兩個date time差了63秒。

時間是個相對的概念

國際通訊協會以經度0度的1970年1月1日0點0時0秒(並不是最嚴謹說法)為相對點,所有的時間都是以和它的秒差記錄。也就是說

經度0度“1970-01-01 00:02:53”在電腦上會記成173(因為它和“1970-01-01 00:00:00”差了2分53秒,總共是173秒)

若時間是以這種方式記錄的,我們會說是UTC時間(Universal Time, Coordinated;亦Coordinated Universal Time)。

lubridate 套件

雖然R本身有時間處理的相關函數,但最好用的還是lubridate這個套件。

library(lubridate)

Download lubridate cheat sheet

產生一個DateTime物件

dtObject<-ymd_hms("1970-01-01 00:02:53") 

產生一個DateTime物件向量:使用c(...)形成向量

dtObjectVector<-ymd_hms(
  c("1970-01-01 00:02:53",
    "1980-02-11 11:25:22")
)

到這一步,電腦就理解dtObject是個date time物件了。

請查詢dtObject的class,驗證R是以date time格式來看待它。

class(dtObject)

“POSIXct” representing calendar dates and times that are stored as a numeric object of seconds following UTC.

POSIX: The Portable Operating System Interface is a family of standards specified by the IEEE Computer Society for maintaining compatibility between operating systems.

螢幕顯示的date time object

dtObject

你要如何顯示電腦儲存的秒數內容呢?

Time zone

由於UTC是以經度0度時區為主,在產生date time物件時,若所指時間不是UTC, 則有必要指定時區。

List of Time Zones: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

顯示目前電腦時區設定

Sys.timezone()

台灣時區

twDateTime <- ymd_hms("2019-03-18 14:04:00", tz="Asia/Taipei")

請在自己螢幕顯示twDateTime,接著顯示電腦儲存的UTC秒數。

For tz input value, the string must be a time zone that is recognized by the user’s OS.

轉成Europe/Lisbon

LisbonDateTime <- with_tz(twDateTime,tzone="Europe/Lisbon")

請在自己螢幕顯示LisbonDateTime,接著顯示電腦儲存的UTC秒數。

請問twDateTime與LisbonDateTime的UTC時間為何?(以螢幕顯示為主)

不管用什麼時區顯示在螢幕,電腦永遠儲存記憶的是UTC秒數。

Other date time format

每個人習慣的date time文字記錄模式都不同,如Google習慣這樣寫“3/14/2019 8:18:47”。

lubridate套件提供以下四大類函數:

ymd_hms(), ymd_hm(), ymd_h()
ydm_hms(), ydm_hm(), ydm_h() 
mdy_hms(), mdy_hm(), mdy_h()
dmy_hms(), dmy_hm(), dmy_h()

你會如何輸入Google的date time讓R理解呢?

Date

lubridate套件提供以下三大類函數來處理日期:

ymd(), ydm()  
mdy(), myd()  
dmy(), dym()  

請讓電腦理解以下兩種日期:

  1. “2018-09-11”

  2. “March 3, 2019”

電腦在存Date時,是該日期與1970-01-01相差的日數:

as.integer(ymd("1970-01-01"))
as.integer(ymd("1970-01-02"))
as.integer(ymd("2019-03-11"))