在正式分析數據前,我們通常需要先預處理一下數據,比如篩選有效樣本,定義變量格式,處理缺失值等,目的是把數據整理成比較清潔的形式,便於後續處理,而R的tidyverse系列工具包針對此提供了豐富多樣的處理方案。本篇內容主要介紹常用的數據導入函數和dplyr包中的一些重要函數。
1 數據導入R支持多種數據格式,最常見的是csv和excel文件。
1.1 導入csv文件read.table()和read.csv()是R基礎包utils中的函數(基礎包會自動加載,相關函數可以直接調用),二者均可讀取csv格式文件。
data <- read.table(file, header = FALSE, sep = "")
data <- read.csv(file, header = TRUE, sep = ",")
兩個函數的主要參數均為前三個參數,其中第一個參數file為文件地址,第二個參數header表示是否以首行為標題,第三個參數sep表示分列符。兩個函數後兩個參數的默認值不同,read.table()默認不以首行為標題、不分列,read.csv默認以首行為標題、以逗號,分列。csv本身是以逗號為分隔的文件,是否以首行為標題要根據實際情況。假設用fileaddress表示文件地址,那麼兩個函數導入csv數據的代碼分別如下:
# 首行為標題
data <- read.table(fileaddress, header = TRUE, sep = ",")
data <- read.csv(fileaddress)
# 首行不為標題
data <- read.table(fileaddress, sep = ",")
data <- read.csv(fileaddress, header = FALSE)
1.2 導入excel文件R基礎包中沒有直接能讀取excel文件的函數,需要借用其他功能包,常用的有readxl和xlsx兩個工具包,對應的函數分別是read_excel()和read.xlsx()。
library(readxl)
data <- read_excel(path, sheet = NULL, col_names = TRUE)
根據excel文件的具體格式可以選擇使用read_xls()和read_xlsx()函數,當批量化讀取數據且兩種格式並存時,可以使用通用函數read_excel()。path參數表示文件地址,sheet參數表示工作表序號,無默認值,col_names參數表示列名,默認為「是」。xlsx包安裝比較麻煩,需要先安裝Java程序。首先進入Java官網,點擊「所有Java下載」,下拉網頁找到對應的Java脫機版本,需要注意的是Java的位數必須與使用的R的位數一致,比如均為64位或32位。Java安裝文件夾默認為「C:\Program Files\Java\jre1.8.0_271」(最後的文件夾編號視版本而變化)不要改動。安裝成功後再在R中運行以下代碼:
install.packages("rJava")
install.packages("xlsxjars")
install.packages("xlsx")
Sys.setenv(JAVA_HOME="C:\\Program Files\\Java\\jre1.8.0_271")Sys.setenv()用於設置系統環境變量,運行後需要重新啟動R才能生效。重啟後就可以正常加載xlsx了。read.xlsx()的主要參數如下:
data <- read.xlsx(file, sheetIndex, header = TRUE, encoding = "unknown")
2 數據篩選、轉換等操作在數據導入後,一般會首先進行刪除無效樣本、變量,利用原有變量生成新變量等操作,常用函數名稱及其功能如下:
filter():按行篩選樣本;
select():按列選擇變量;
mutate:根據一個或多個變量生成新變量或重定義已有變量,原變量仍然保留;
transmute():根據一個或多個變量生成新變量或重定義已有變量後,其他變量不再保留。library(tidyverse)
data <- mtcars # 假設導入的數據
summary(data) # 查看data的變量和數據特徵
data %>%
filter(cyl == 6) %>% # 樣本篩選操作,只保留變量cyl為6的樣本
select(mpg, disp, hp) %>% # 變量選擇操作,只保留這三個變量
select(-mpg) %>% # 變量反向選擇操作,刪去此變量,其他變量保留
mutate(newvar = disp * hp) -> newdata # 生成新變量操作
newdata %>%
transmute(newvar = disp * hp) -> newdata2
3 數據框拼接、連接操作數據框的合併是指將兩個數據框整合成一個數據框,分為直接按行或列拼接和按共同變量連接兩種,常用的函數名稱及功能如下:
bind_cols:增加列合併,將兩個數據框相同行拼接成同一行,要求它們行數相同,即
R基礎包中的cbind()和rbind()函數也有類似功能,但運行速度較慢。left_join():左連接,即以第一個數據框為參照;
這兩個連接方案會保留參照數據框的所有行,而非參照數據框只保留能匹配到參照數據框的行,參照數據框不能匹配非參照數據框的行對應非參照數據框的變量記為NA;無論是左連接 還是右連接,合併後的數據框變量排序都是第一個數據框的原變量在前,第二個數據框的原變量在後;如果非參照數據框有多行與參照數據框的一行對應,那麼合併後的數據框相比於參照數據框會多出若干行以一一連接這些行。
right_join():右連接,即以第二個數據框為參照。full_join():全連接,保留兩個數據框所有的行,不能匹配的行對應變量記為NA;
inner_join():內連接,只保留兩個數據框能匹配的行;
semi_join():半連接,保留第一個數據框能與第二個數據框匹配的內容,但不把第二個數據框的變量加入合併的數據框;
anti_join():反向連接,保留第一個數據框不能與第二個數據框匹配的內容。library(tidyverse)
# 準備兩個數據框,ID為公共變量
df1 <- mtcars %>%
slice(1 : 10) %>%
select(mpg) %>%
mutate(ID = c(1 : 10))
df2 <- iris %>%
slice(1 : 12) %>%
select(Sepal.Length) %>%
mutate(ID = floor(runif(12, min = 2, max = 11)))
# left_join
left_join(df1, df2, by = "ID")
# 公共變量名稱在兩個數據框中不同
df11 <- rename(df1, ID1 = ID)
df22 <- rename(df2, ID2 = ID)
left_join(df11, df22, by = c("ID1" = "ID2"))
# right_join
right_join(df1, df2, by = "ID")
# full_join
full_join(df1, df2, by = "ID")
# inner_join
inner_join(df1, df2, by = "ID")
# semi_join
semi_join(df1, df2, by = "ID")
# anti_join
anti_join(df1, df2, by = "ID")
4 命名、排序、分組等操作rename:重命名變量;
arrange():按變量進行行排序,優先級高的變量寫在前面,默認升序,降序時使用desc(var);
relocate():改變變量的列順序;
group_by():按變量分組;
ungroup():取消分組;
summarise():匯總操作。summary(mtcars)
mtcars %>%
select(mpg, disp, hp, cyl) %>%
slice(1 : 10) %>%
rename(mpg1 = mpg) %>%
arrange(disp, desc(hp)) %>% # 按disp升序、hp降序排序
relocate(hp, disp) %>% # 將變量hp移到disp前面
group_by(cyl) %>% # 按cyl分組
mutate(mean = mean(disp)) %>% # 按以上分組求disp的均值
ungroup() -> data # 取消分組
data %>%
group_by(cyl) %>%
summarise(mean = mean(disp), n = n()) # 匯總