關卡 1

在R 中,我們操作的所有變數,都是一種R 物件(Object)。 這一堂課程中,就是要簡介R 的物件結構。

關卡 2

在所有物件中,最基礎的「原子」物件,就是在上一堂課中介紹的各種向量。 其他的物件都是由這些原子物件組合而成。

關卡 3

向量物件有兩個很重要的屬性:modelengthmode代表這個向量的值型態,總共有:logicalintegernumericcomplexcharacterrawlength則代表這個向量中值的個數。

關卡 4

若要查詢一個向量的型態和長度,可以使用函數modelength。 請同學試試看:mode(x)

mode(x)

關卡 5

請問x 的型態是?

numeric

關卡 6

接著,請試試看length(x)

length(x)

關卡 7

請問x 的長度是?

5

關卡 8

R 也可以建立一種叫做list的向量,這是「R 物件」的向量。 在此向量中,每一個值都是R 物件,都具有各自的modelength等屬性。我們會在較為複雜的統計模型中,見到這樣的資料型態。 舉例來說,在R 中如果要建立一個迴歸模型,會使用:g <- lm(dist ~ speed, cars) 這樣的程式碼會利用車速當解釋變數、煞車距離當應變數,建立一個迴歸模型。 先不管lm如何使用,上述的例子主要是希望能讓同學了解g這個物件的結構。 只要掌握這部分的課程內容,未來就可以輕鬆的探索更多機器學習或統計分析演算法的輸出結果。

關卡 9

請同學檢查g的型態。

mode(g)

關卡 10

請同學檢查g的長度。

length(g)

關卡 11

在上一個章節中提及,可以使用如g[1:2]的方式取出g的第一個到第二個值。 而這樣的輸出結果和g會有同樣的mode。 請同學試看看g[1:2]的結果。

g[1:2]

關卡 12

同學會在R console看到一些數字以及文字出現。 在最上面的$coefficients,表示g[1:2]這個向量的第一個值(同時也是g的第一個值),是有名字的。而它的名字是:"coefficients"。 由於g[1:2]的第一個值是一個有名字的numeric 向量,R 就把這個向量所有的名字和值一起顯示在console之中。 而這個numeric 向量的第一個值是-17.579095,名字是"(Intercept)"。第二個值是3.932409,名字則是"speed"

關卡 13

接著,$residuals表示g[1:2]的第二個值也是有名字的,而且它的名字是"residuals"。 由於這個值也是一個有名字的numeric 向量,所以R 就把值和名字同時顯示到console上。 所以我們就可以知道,這個numeric 向量的第一個值的名字是"1",值是3.849460。以此類推。

關卡 14

然而,整個R Console的結果顯示,g[1:2]仍然是一個list,因為R 只有在顯示list的內容 才會帶有$coefficients$residuals這種標記。如果只是一個numeric 向量,就不會顯示出 $coefficients$residuals

關卡 15

請同學輸入list(1, a = 2)來看看R 如何顯示list,並比較當值有附帶名字及沒有附帶名字時,輸出結果的不同。

list(1, a = 2)

關卡 16

在輸出結果的一開始,R 顯示了[[1]],接著顯示一個值為1 的numeric 向量。 開頭的[[1]]不只說明了這個物件是一個list,也說明接下來顯示的是第一個值的內容。

關卡 17

接著,R 顯示了$a,以及顯示一個值為2 的numeric 向量。 開頭的$a因為位置在上述的[[1]]之後,所以代表這是這個list物件的第二個值。 同時,這個值的名字是"a"

關卡 18

若想找出g的第一個值的物件本身,而非被包在一個list中,我們需要用到:g[[1]]。 請同學試試看。

g[[1]]

關卡 19

請同學查詢g[[1]]的型態。

mode(g[[1]])

關卡 20

請同學查詢g[[1]]的長度。

length(g[[1]])

關卡 21

再針對g[1]g[[1]]的差異進行說明一次。 使用g[1]時,R 取出向量的第一個元素,並且維持list的結構,所以g[1]的結果還仍是list。 相反的,使用g[[1]]時,R 會打破list的結構,再取出向量的第一個元素,所以g[[1]]的型態會是存放在list裡面的R 物件的型態。 在上述的例子中,因為g 這個list的第一個存放的R 物件是numeric向量,所以得到g[1]的型態是list,g[[1]]的型態則是numeric。

關卡 22

一般來說,對R 物件使用[]之後,會取得和該物件相同型態的物件。 所以a[1]的型態會和a一樣,而[[]]就沒有類似的特性了。

關卡 23

經過上述的練習,相信同學可以理解list這個「R 物件的向量」所代表的意義。 list向量最實用的特性,在於它可以裝不同型態的值。 以g為範例,雖然大部分值的型態都是numeric,但是也有些型態為call和list的物件。 list向量讓R 的開發者能更有彈性的建立較為複雜的模型。 同學在學會list之後,也可以更有能力來了解不同R 套件所建立的模型物件。

關卡 24

請同學檢查看看g[[10]]的型態。

mode(g[[10]])

關卡 25

這裡的g[[10]]其實是記載著產生g 的程式碼。在R 裡面,這樣的程式碼是存成call型態的物件。 我們現在只要知道這是一種call就可以了。至於call是什麼東西,要等到同學需要開始深入的學習R 的原始碼、運作機制時, 才需要弄懂。我們現在只要知道,list可以裝所有R 的物件就可以了。

關卡 26

另外,我們也可以為list命名。 上述例子中,我們除了用g[[1]]來取得第一個值之外,也可以用g[["coefficients"]]來取得第一個值。 因為g這個向量是被命名的,而第一個名字就是"coefficients"。 請同學試試看。

g[["coefficients"]]

關卡 27

適當的命名,可以讓程式碼更易讀。 舉例來說,若知道g是一個迴歸模型,也知道迴歸模型通常就是一個參數向量,那我們就可以預期到g[["coefficients"]]就是這個迴歸模型的參數。 (在統計學之中,不同迴歸模型的參數通常稱作:“coefficients”)。

關卡 28

我們可以更改一個向量的長度。 舉例來說,現在x 是一個長度是5 、型態是numeric的向量。 我們可以利用:length(x) <- 10把x 的長度改成10。請同學試試看。

length(x) <- 10

關卡 29

現在我們可以來看看x 的值。,請同學輸入:x

x

關卡 30

我們也可以直接在x 的指定位置中放入新的值,並且藉此增加x 的長度。 舉例來說:x[7] <- 7可以讓x 的第7 個位置的值變成7 。請同學試試看。

x[7] <- 7

關卡 31

現在我們可以來看看x 的值。,請同學輸入:x

x

關卡 32

由於x 本來的長度就已經超過7 ,所以並沒有延長。 請同學換一個程式試試看:x[13] <- 13

x[13] <- 13

關卡 33

現在我們可以來看看x 的值。,請同學輸入:x

x

關卡 34

如果我們要縮短x 的長度,可以運用如:x2 <- x[c(1,3,5,7,9,11,13)],這樣得出的x2就會是縮短的x 。 請同學試試看。

x2 <- x[c(1,3,5,7,9,11,13)]

關卡 35

現在我們可以來看看x2的值。,請同學輸入:x2

x2

關卡 36

由結果中發現,x2只剩下原本在x 奇數位置的值了。 在整理資料時,我們常常需要這樣的技巧,來從資料中選出我們真正要分析的部份,並調整成我們需要的長度。

關卡 37

所有的R 物件,都有「屬性」(attributes)。我們可以用attributes這個函數來印出一個R 物件的屬性。 請同學試試看:attributes(g)

attributes(g)

關卡 38

根據剛剛的輸出結果,attributes(g)的屬性應該是哪一種向量呢?

list

關卡 39

進入下一個題目之前,請同學先輸入names(g)來查詢g的名字,並和attributes(g)的結果做比對。

names(g)

關卡 40

attributes(g)的輸出結果中,會看到一個帶有名字的list。 請同學記得,所有R 物件的attributes都是帶有名字的list。

關卡 41

而這個物件的名字,就是attributes(g)這個list中,名字為"names"的值,而且值一定是character向量。 在R 中可以用attr(g, "names")來取得名字是“names”的屬性。請同學試試看。

attr(g, "names")

關卡 42

上一題的輸出結果,就是g 這個list的名字,也是names(g)的結果。

關卡 43

回到attributes(g)的輸出。 除了第一個值是名字為"names"的character向量之外,第二個值是一個名為"class"的character向量。 character向量的值是"lm"。 請同學試試看:attr(g, "class")

attr(g, "class")

關卡 44

attributes這樣的功能在探索一些複雜的R 模型物件時是非常好用的。 我們在之後深入探討matrixdata.frame等進階物件的時候,也會需要了解attributes的相關知識。 現在,同學只要知道所有的R 物件都具有attributes就可以了。

關卡 45

而名稱為“class”的屬性是非常重要的,因為它牽涉到R 的物件導向設計。 這部份將會在更進階的章節中,再跟同學說明。

關卡 46

由於“names”和“class”這兩個屬性是如此的重要,所以R 中設計有classnames這兩個函數, 讓使用者可以針對一個R 物件的names和class進行修改。請同學試試看:names(g)

names(g)

關卡 47

再請同學試試看:class(g)

class(g)

關卡 48

這個課程簡介了R 的物件系統。 希望未來同學在接觸到沒學過的套件時,可以有系統地來摸索R 套件的輸出。

關卡 49

最後,我們請同學用本課程中所學的內容,處理一個PCA 的結果。 請同學在完成之後存檔,並輸入submit()來檢查結果是否符合預期。 如果同學在檔案中看到亂碼,請使用Rstudio 左上角的File -> Reopen With Encoding… -> 選取:UTF-8

#' 以下內容改自prcomp 的範例程式碼
#'
#' PCA(Principle Components Analysis) 是一個資料分析時常用的技術,
#' 它的原理會在後面的課程講解。
#' 在R 中,我們可以利用prcomp這個指令對USArrests這筆資料進行PCA 的分析,
#' R 會吐回一個計算後的物件給我們。
pca <- prcomp(USArrests, scale = TRUE)

#' 請同學找出pca的「型態」。你的答案只可能是:「"character"」、「"numeric"」或「"list"」
answer1 <- mode(pca)

#' 請同學將pca的長度寫入變數answer2
answer2 <- length(pca)

#' 請同學將pca的名字寫入變數answer3
answer3 <- names(pca)

#' pca 的元素中,有一個是各個principal components的standard deviations。
#' 請同學參考help(prcomp)的說明的Value章節
#' 將各個principal components的standard deviations
#' 寫入變數answer4

# 也可以使用教材中教的 `pca[["sdev"]]` ,這裡`[[`與`$`都有從list拿出物件的功能
answer4 <- pca$sdev

#' pca 的元素中,有一個是PCA的中心(center)。請同學參考help(prcomp)的說明,
#' 將該元素寫入變數answer5
answer5 <- pca$center