R 資料的子集合(Subsets)
接下來我們要介紹如何從 Squid 這個 data frame 中萃取部分的資料出來,這個資料篩選的方式可以適用於任何的 data frame。
假設我們想要篩選出所有性別欄位(Sex)是男性或女性的資料,首先我們先看一下 Sex 裡面的資料:
Squid$Sex
資料大概是這個樣子:
[1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 [20] 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 [39] 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 [略]
由於資料筆數很多,很難看出到底有哪一些值,我們可以用 unique 來將重複的數值去掉:
unique(Squid$Sex)
輸出為
[1] 2 1
這裡的 1 代表男性,而 2 代表女性,若要篩選出男性的資料,可以執行:
Sel <- Squid$Sex == 1 SquidM <- Squid[Sel, ] SquidM
輸出為
Sample Year Month Location Sex GSI 24 24 1 5 1 1 5.2970 48 48 1 5 3 1 4.2968 58 58 1 6 1 1 3.5008 60 60 1 6 1 1 3.2487 61 61 1 6 1 1 3.2304 [略]
這裡的第一行 Squid$Sex == 1 會檢查 Sex 的每一個值是否為 1,產生一個跟 Sex 一樣長度的向量,若 Sex 對應的值為 1,則產生 TRUE,若 Sex 的值不是 1,則產生 FALSE,而這樣的向量稱為布林向量(boolean vector),在篩選資料時通常都會透過這樣的方式來指定子集合,因此我們將這個向量名為 Sel。
第二行的 Squid[Sel, ] 是選擇所有 Sel 的值為 TRUE 的資料,並將這些資料儲存在 SquidM 中。
我們也可以將第一行與第二行合併,寫成:
SquidM <- Squid[Squid$Sex == 1, ] SquidM
若要篩選出女性的資料,可以執行:
SquidF <- Squid[Squid$Sex == 2, ] SquidF
這種透過布林向量篩選資料的方法可以用在非常多的地方,我們接下來想要根據 Location 這個欄位來篩選資料,首先看一下 unique 的結果:
unique(Squid$Location)
輸出為
[1] 1 3 4 2
如果我們想要篩選出 Location 是 1、2 或 3 的資料,可以有以下幾種方式:
Squid123 <- Squid[Squid$Location == 1 | Squid$Location == 2 | Squid$Location == 3, ] Squid123 <- Squid[Squid$Location != 4, ] Squid123 <- Squid[Squid$Location < 4, ] Squid123 <- Squid[Squid$Location <= 3, ] Squid123 <- Squid[Squid$Location >= 1 & Squid$Location <= 3, ]
第一行是利用 OR 運算子(|),將三個 == 的判斷結果結合起來,而第二行是直接判斷 Location 是否不等於(!=)4,第三行與第四行則是使用「小於」(<)以及「小於或等於」(<=)來判斷,最後一行則是將兩個判斷結果用 AND 運算子(&)結合,在這個例子中不管用哪一種寫法都可以獲得同樣的結果。
我們也可以同時使用多個欄位來產生布林向量,例如選擇 Sex 為 1 而且 Location 為 1 的資料:
SquidM.1 <- Squid[Squid$Sex == 1 & Squid$Location == 1,]
選擇 Sex 為 1 而且 Location 為 1 或 2 的資料:
SquidM.12 <- Squid[Squid$Sex == 1 & (Squid$Location == 1 | Squid$Location == 2), ]
有些初學者在產生布林向量時,很容易犯下這樣的錯誤:
SquidM <- Squid[Squid$Sex == 1, ] SquidM1 <- SquidM[Squid$Location == 1, ] SquidM1
輸出會像這樣:
Sample Year Month Location Sex 24 24 1 5 1 1 58 58 1 6 1 1 [略] NA NA NA NA NA NA NA.1 NA NA NA NA NA NA.2 NA NA NA NA NA [略]
這裡的第一行篩選出所有男性的資料,並儲存至 SquidM,因此 SquidM 的資料筆數會小於原來 Squid 的資料筆數(假設 Squid 中有女性的資料),因此在第二行中 Squid$Location==1 的長度會比 SquidM 的資料筆數還要多,多出來的部分就會以 NA 遞補,因此產生這樣奇怪的結果。若要修正這個錯誤,應該要改成這樣:
SquidM <- Squid[Squid$Sex == 1, ] SquidM1 <- SquidM[SquidM$Location == 1, ] SquidM1
另外如果沒有任何資料符合篩選的條件,狀況會類似這樣:
Squid[Squid$Location == 1 & Squid$Year == 4 & Squid$Month == 1, ]
輸出為
[1] Sample Year Month Location [5] Sex GSI (or 0-length row.names)
山崎退
新手發問~~小弟沒有資訊背景,剛接觸R不久
請問文章開頭的資料檔squid.txt是需自行建立嗎?
或者是有載點可下載
蠻希望跟著板主的文章來練習
若有不妥還請包涵~~感謝!
G. T. Wang
是我忘記放下載連結,真是抱歉!
我已經將下載連結放在文章中了,如果還有其他問題請再跟我說,謝謝您。