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: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()是對矩陣做轉置,可以丟向量進去,但是輸出是矩陣,轉置兩次會變回自己,但是是矩陣版本的。
 
二維: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
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, 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[[3]]
> D[[2]][3]
> D[[c(2, 3)]] 
> D[-3]; D[1:2]
> D[[-3]]
 
data.frame和list都可以試一下單引號和雙引號的差異:
1. 一樣在取第二項,D[2]還是個listD[[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、各種雜七雜八的物件。
arrow
arrow
    創作者介紹
    創作者 霹靂貓 的頭像
    霹靂貓

    生活統計二三事

    霹靂貓 發表在 痞客邦 留言(0) 人氣()