關卡 1
在R 中,我們操作的所有變數,都是一種R 物件(Object)。 這一堂課程中,就是要簡介R 的物件結構。
關卡 2
在所有物件中,最基礎的「原子」物件,就是在上一堂課中介紹的各種向量。 其他的物件都是由這些原子物件組合而成。
關卡 3
向量物件有兩個很重要的屬性:mode
和length
。 mode
代表這個向量的值型態,總共有:logical
、integer
、numeric
、complex
、character
和raw
。 length
則代表這個向量中值的個數。
關卡 4
若要查詢一個向量的型態和長度,可以使用函數mode
和length
。 請同學試試看:mode(x)
。
mode(x)
關卡 5
請問x 的型態是?
numeric
關卡 6
接著,請試試看length(x)
。
length(x)
關卡 7
請問x 的長度是?
5
關卡 8
R 也可以建立一種叫做list
的向量,這是「R 物件」的向量。 在此向量中,每一個值都是R 物件,都具有各自的mode
、length
等屬性。我們會在較為複雜的統計模型中,見到這樣的資料型態。 舉例來說,在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 模型物件時是非常好用的。 我們在之後深入探討matrix
、data.frame
等進階物件的時候,也會需要了解attributes的相關知識。 現在,同學只要知道所有的R 物件都具有attributes就可以了。
關卡 45
而名稱為“class”的屬性是非常重要的,因為它牽涉到R 的物件導向設計。 這部份將會在更進階的章節中,再跟同學說明。
關卡 46
由於“names”和“class”這兩個屬性是如此的重要,所以R 中設計有class
和names
這兩個函數, 讓使用者可以針對一個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