close
這一篇介紹使用[ ],從一個物件中提取數據的基本原則:
[ ]中提取物件中的數據主要是以物件的維度來看怎麼提取:
一維 ex. vector 向量,一串東西排在一起
二維 ex. matrix or data.frame
三維以上 ex. array
亂七八糟的東西湊成 ex. list 列表
下面是各種例子,就不放output了,有興趣的直接打到R裡面看結果就知道了。
一維:數字或文字的向量(vector)...只要是一串東西,都用一位數字放在[ ]取內部的資料:
> (A <- 1:10) # int, vector
> letters[-c(5:20)] # delete
> letters[26:1]; rev(letters) # reverse
> LETTERS[c(16, 5, 9, 12, 9)] # 猜猜它是什麼
> A[length(A)-c(1:0)]; tail(A, 2) # tail
裡面的:是seq()函數的簡化版,seqence就是數列,seq()有更完整的造數列的功能。
看完上面的例子,會發現[ ]取資料的應用還包含了重新排序和刪除部份資料的功能,而且有些功能也可以叫某個函數來做,結果一樣。
另外,補充一件平常不怎麼重要但有時候會帶來一點麻煩的事:任何一維的向量,雖然印出來都是一列東西在那,但在矩陣運算裡視為”行向量”,也就是他是排直的。
雖然一列東西在那通常是向量,但是也有只有1行或1列matrix的例子:看下面的例子,比較結果就知道了。
雖然一列東西在那通常是向量,但是也有只有1行或1列matrix的例子:看下面的例子,比較結果就知道了。
> 1:3 # vector
[1] 1 2 3
> t(1:3) # matrix
[,1] [,2] [,3]
[1,] 1 2 3
> t(t(1:3)) # matrix version of the vector 1:3
[,1]
[1,] 1
[2,] 2
[3,] 3
> t(1:3)[1, ] # vector
[1] 1 2 3
> t(1:3) # matrix
[,1] [,2] [,3]
[1,] 1 2 3
> t(t(1:3)) # matrix version of the vector 1:3
[,1]
[1,] 1
[2,] 2
[3,] 3
> t(1:3)[1, ] # vector
[1] 1 2 3
t()是對矩陣做轉置,可以丟向量進去,但是輸出是矩陣,轉置兩次會變回自己,但是是矩陣版本的。
二維:matrix或data.frame:看了前面的例子就知道,自然就是要兩位數字來定坐標了,順序是[row列位, column欄位]。
matrix不一定要有行列名(row/column name),但是轉換成data.frame的時候,都會自動補上row name和column name。對於這種有帶名稱的行列,除了給數字坐標定位,也可以用名字。記得不管行列名是什麼,當它是名字時,一定是"文字"。
> M1 <- matrix(1:20, ncol=5)
> M2 <- as.data.frame(M1)
> (M2 <- M2[c(1, 3, 2, 4),])
V1 V2 V3 V4 V5
1 1 5 9 13 17
3 3 7 11 15 19
2 2 6 10 14 18
4 4 8 12 16 20
這邊先故意把M2的列重排,讓row name順序打亂,讓大家看看針對名字和位置取的不同:
> M2[paste(1:3), "V2"]
[1] 5 6 7
paste(1:3)後的數字會加上""產文字符號,因此對應到列名(而不是順序),照數字座標定位的話,結果應該是:
> M2[1:3, "V2"]
[1] 5 7 6
趁這個機會可以看到同樣是二維的物件,matrix和data.frame的一項差別:在二維的世界裡確實也可以輸入一個數字定位,但是matrix和data.frame結果差很多。
> M1[1]
[1] 1
> M2[1]
V1
1 1
3 3
2 2
> M2[1]
V1
1 1
3 3
2 2
4 4
matrix是由一個個數字或文字排成陣列,而data.frame是由一行行變數併排在一起。在這樣的原理下,M1[1]只有一個元素,M2[1]是一欄變數。也因此,matrix裡所有元素都是同一類,只要有一個文字符號(character)出現,就會全部視為文字,而data.frame每一欄可以有各自的屬性,像上一篇提到的iris裡就有number和factor兩種。
> c(1, 2, "C")
[1] "1" "2" "C"
這個向量裡1, 2都變成字符了。[什麼?你看到向量裡有文字和數字混合?那一定是NA或Inf這一類特殊意義的保留字(Reserved Word)不是Character喔!找機會寫一些和它們有關...有興趣可以先 ?Reserved 看看哪些是保留字。]
陣列(array)在一維的時候是vector,二維的時候是matrix,所以它們在性質和取用上和matrix是一樣的,它們都不允許文字和數字共存的,想象一下:如果有一個變數叫身材,結果裡面用不同的方式記錄每個人的情況,有的寫”高”,”瘦”,120,175,50,”壯”,80,160,你大概也會覺得這是什麼亂七八糟的東西吧....
了解matrix後,更高維的array沒什麼好說的,大家自己玩吧。
> (A <- array(1:60, dim=c(5, 6, 2))) # 3-dim array
> A[, , 1]
> A[, , 1]
> A[-1, 3:2, 2]
PS 好像都沒有提到 # 後的字執行程式時都會被忽略,對程式加註解用的。
最後用一個小list來收尾。我建了一個有3項物件的list。第一項是一個數字向量,第二項是文字向量,第三項裡又是個list。自己試著用[[]]或[]提取想要的資料吧!裡面有一個是ERROR喔!
> (D <- list(1:4, letters[1:4], list("pi", pi)))# list
> D[2]
> D[[2]]
> D[2]
> D[[2]]
> D[[3]]
> D[[2]][3]
> D[[c(2, 3)]]
> D[-3]; D[1:2]
> D[-3]; D[1:2]
> D[[-3]]
data.frame和list都可以試一下單引號和雙引號的差異:
1. 一樣在取第二項,D[2]還是個list,D[[2]]才會取出向量。(類似的事情也發生在data.frame裡,M2[1]是data.frame,M2[[1]]才是向量。)
2. D[-3]會刪掉list的第三項,在這裡等同於D[1:2],但是D[[-3]]是ERROR!
3. D[1:2]是取前兩項,而D[[c(2, 3)]]是第二項第三位,等同於D[[2]][3]。
小結:
物件大約分成兩派:
物件大約分成兩派:
1. array族的有一維vector, 二維的matrix, 和更高階的array:基本的組成單元是一個個數字或文字,所有單元結構都相同。
2. 較複雜的data.frame和list:基本的組成單元是一欄欄變數或一個個項目,每一欄或每一項可以有各自的結構。
用[]可以同時取多個單元,取出來的資料會維特原來物件的結構,用在array會降維度,用在data.frame或list會變成更小的data.frame或list。
用[[]]一次只能取一個單元,結構的話就是該單元的結構。
用[[]]一次只能取一個單元,結構的話就是該單元的結構。
Lesson 3 從物件裡提取數據的必殺技 :如何應付和面對各種funtion吐出的各種output、各種雜七雜八的物件。
文章標籤
全站熱搜