R 變數與資料的管理

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

如果我們想要篩選出 Location123 的資料,可以有以下幾種方式:

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 運算子(&)結合,在這個例子中不管用哪一種寫法都可以獲得同樣的結果。

我們也可以同時使用多個欄位來產生布林向量,例如選擇 Sex1 而且 Location1 的資料:

SquidM.1 <- Squid[Squid$Sex == 1 & Squid$Location == 1,]

選擇 Sex1 而且 Location12 的資料:

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

2 留言

  1. 山崎退

    新手發問~~小弟沒有資訊背景,剛接觸R不久
    請問文章開頭的資料檔squid.txt是需自行建立嗎?
    或者是有載點可下載
    蠻希望跟著板主的文章來練習
    若有不妥還請包涵~~感謝!

    • G. T. Wang

      是我忘記放下載連結,真是抱歉!

      我已經將下載連結放在文章中了,如果還有其他問題請再跟我說,謝謝您。

Comments are Closed