由於微信不允許外部連結,你需要點擊文章尾部左下角的 "閱讀原文",才能訪問文中連結。
通常,我們在使用大型數據集時,只會對其中的一小部分感興趣,用以進行特定分析。 那麼,我們應該如何對所有無關的變量和觀察值進行排序並僅提取我們需要的那部分數據? 其實,在 R 中有幾種被稱為 「subsetting(子集化)」 的方法可以滿足以上的需求,今天我們來聊一下。
在 R 中對數據框(data frame)進行子集化的最基本方法是使用方括號:
example[x, y]
example 是我們想要從中提取子集的數據框;』x』是我們想要提取的子集的行;』y』 是我們想要提取的子集的列。 讓我們從網上提取一些數據,看看它是如何在真實的數據集上實現的。
### import education expenditure data setand assign column nameseducation <- read.csv("https://vincentarelbundock.github.io/Rdatasets/csv/robustbase/education.csv", stringsAsFactors = FALSE)colnames(education) <- c("X","State","Region","Urban.Population","Per.Capita.Income","Minor.Population","Education.Expenditures")head(education, 25)
這是我導入數據並適當命名其列後數據集的第一部分(前 25 行):
現在,讓我們假設回顧一下美國中西部的學校分布,並且我們需要計算 Region 2 地區中每個州每個孩子花費了多少錢。 我們需要三個變量:State,Minor.Population 和 Education.Expenditures。 但是,我們只需要對應於 Region 2 的行的觀察結果。這是在 R 中檢索該數據的基本方法:
ed_exp1 <- education[c(10:21), c(2, 6:7)]
為了創建新的數據框 『ed_exp1』,我們通過提取第 10-21 行和第 2, 6 和 7 列來對 「education(教育)」 數據框進行子集化。非常簡單,對吧?
使用括號對數據框進行子集化的另一種方法是省略行和列引用(即反取)。 看看這段代碼:
ed_exp2 <- education[-c(1:9, 22:50),-c(1, 3:5)]
在這行代碼裡,我們不是對我們想要返回的行和列進行子集化,而是對我們不希望返回的行和列進行子集化,然後使用 「-」 符號省略它們。 如果我們現在調用 ed_exp1 和 ed_exp2,我們可以看到兩個數據框都返回原始 education 數據框相同的子集。
上面這些在 R 中對小數據框進行子集的基本方法在大型數據集中會變得單調缺乏靈活性,因為我們必須知道所要提取的子集的確切列和行索引號。如果一個數據只有 7 列 50 行,找到所需的列和行會非常簡單,但是如果這個數據有 70 列和 5000 行呢?在這種情況下,如何找到所需的列和行?下面是另一種在 R 中提取數據框子集的方法。
ed_exp3 <- education[which(education$Region == 2), names(education) %in% c("State", "Minor.Population", "Education.Expenditures")]
我們來看看這段命令發生了什麼。
首先,我們使用了跟前兩個例子一樣的方括號技術來提取 education 數據框的子集。但是,這一次,我們使用了 which()函數提取我們需要的行。 此函數返回了 education 數據框中 Region 列值為 2 的索引。這為我們提供了所需的行。
然後,我們通過在 education 數據框的名稱上使用 %in%運算符來檢索子集的列。
現在,有些人看著這行代碼覺得它太複雜了。 必須有一種更簡單的方法來做到這一點。 好吧,你會是對的。 R 中還有另一個基本功能,它允許我們在不知道行和列引用的情況下對數據框進行子集化。 使用名字來提取? 你猜對了:subset()。
ed_exp4 <- subset(education, Region == 2, select = c("State","Minor.Population","Education.Expenditures"))
subset()函數有 3 個參數:我們想要子集化的數據框,我們希望它進行子集化處理對應的行,以及我們想要返回的列。 在我們的例子中,我們採用 「Region」 等於 2 的 education 子集,然後選擇 「State」, 」Minor.Population」 和 「Education.Expenditure」 列。
當我們使用上述兩種方法中的任何一種對 education 數據框進行子集化時,我們得到與前兩種方法相同的結果:
除此以外,還有一種我們操作數據最有用的方法。讓我們先來看看代碼,然後我們將討論它。
install.packages("dplyr")library(dplyr)ed_exp5 <- select(filter(education, Region == 2),c(State,Minor.Population:Education.Expenditures))
最後的這一種方法不是 R 基礎環境的一部分。要使用它,我們必須安裝並下載 dplyr軟體包。如果你要使用 R 中的數據,這肯定是一個你想要的包。 它是 R 環境中下載次數最多的軟體包之一,當你開始使用它時,你很快就會明白為什麼。
因此,一旦我們下載了 dplyr,我們就可以使用此包中的兩個不同函數創建一個新的數據框:
filter:第一個參數是數據框; 第二個參數是我們希望它被子集化的條件。 結果是整個數據框只有我們想要的行。
select:第一個參數是數據框; 第二個參數是我們想要從中選擇的列的名稱。我們不必使用 names()函數,甚至不必使用引號。 我們只是將列名列為對象就可以。
在這個例子中,我們將篩選函數(filter)包裝在選擇函數(select)中以返回我們的數據框。 換句話說,我們首先將 Region 為 2 的行作為子集。 然後,我們從那些行中獲取了我們想要的列。 結果為我們提供了一個數據框架,其中包含我們感興趣的 12 個州所需的數據:
最後,回顧一下,這裡有 5 種方法可以在 R 中對數據框進行子集化:
使用括號,通過提取我們想要的行和列來進行子集化;使用括號,通過省略我們不想要的行和列來進行子集化;使用括號,使用 which() 函數和 %in%運算符組合進行子集化;使用 subset()函數;使用 dplyr 包中的 filter()和 select() 函數實現數據框子集化。