一、plyr包
plyr擴展包主要是實現數據處理中的“分割-應用-組合”(split-apply-combine)策略。此策略是指將一個問題分割成更容易操作的部分,再對每一部分進行獨立的操作,最后將各部分的操作結果組合起來。
plyr擴展包中的主要函數可以用**ply來概括:第一個 * 表示輸入數據的結構,可選的數據結構有a(array)、d(data.frame)和 l (list);第二個 * 表示輸出數據的結構,可選的數據結構除了前面3種以外,還有“_”,它表示不輸出,它的結果常用于繪圖和建立緩存。
輸入 | 輸出數組 | 輸出數據框 | 輸出數據列表 | 無輸出 |
數組 | aaply | adply | alply | a_ply |
數據框 | daply | ddply | dlply | d_ply |
列表 | laply | ldply | llply | l_ply |
?按照輸入數據的結構可以分為3類:
a*ply(.data, .margins, .fun, ..., .progress="none"):按照維度對數組進行“切片”;
d*ply(.data, .variables, .fun, ..., .progress="none"):按照一列或多列將數據框分為若干子集;
l*ply(.data, .fun, ..., .progress="none"):將列表的每個分量作為子集。
?參數詳解:
.data:表示輸入數據;
.margins:表示數組的邊際,與apply函數的MARGIN類似,也可以為向量。用來描述輸入數據將如何被分割為若干部分;
.variables:表示分組變量,可以有多個變量。用來描述輸入數據將如何被分割為若干部分。
.fun:表示應用于數據各部分的函數,如果沒有指定.fun,則表示從一種數據結構變為另一種數據結構;
...:表示傳遞給.fun的其它參數;
.progress:表示進度條的類型,none表示不顯示進度條,它有text,tk和win三種進度條。
下面用datasets包中的鳶尾花數據集iris和iris3舉例:
library(plyr)
iris.set <- iris
iris3.set <- iris3
class(iris)
class(iris3)
?
若不在.fun指定應用函數,**ply()函數的作用僅僅是將數據集從一種結構轉換為另一種結構。
iris.set1 <- dlply(iris.set, .variables="Species")
head(iris.set1)
二、dplyr包
plyr
?包雖然功能強大,但在處理大數據集時可能會比較慢。對于更高效的數據處理,可以考慮使用?dplyr
?包,它是?plyr
?的一個現代替代品,提供了更快的速度和更直觀的語法。
dplyr包主要針對數據框和tibble(tbl_df對象,一種增強的數據框)的操作。tibble數據結構在呈現大型數據集時非常友好。
下面以nyflights13擴展包中的flights數據集為例,此數據集中包含了336776次航班信息。(先安裝install.packages("nyflights13")。
flights數據集就是一個tibble類型的數據框,它和一般數據框的區別是,當打印到控制臺上時會附帶上更多的信息。例如,行數和列數,每一列的數據類型,少量的數據示例及省略的行數、列數和列名。
?1、select()函數
用于選擇需要的變量用在后續的分析上。
library(dplyr)
# 選擇列變量
head(select(flights, year, flight, dest))
如果要從數據中刪除一些變量,可以通過在變量前添加負號(-)來實現。另外,在select()函數中還可以使用一些輔助函數來完成對列的匹配操作:starts_with()、ends_with()、contains()、matches()、num_range()、one_of()和everything()等。
選取以“a”為首字母的變量
library(dplyr)
# 選擇以“a”為首字母的變量
head(select(flights, starts_with("a")))
?選取包含“lay”的變量
library(dplyr)
head(select(flights, contains("lay")))
選取最后單詞為“.time”的變量
library(dplyr)
head(select(flights, matches(".time")))
2、filter()函數
?用于根據條件對數據的列或者記錄進行篩選。
# 選取在7月19日起飛,并且飛行距離大于800的AS或HA航空公司的航班信息
filter(flights, month==7,day==19,distance>800,carrier=="AS"|carrier=="HA")
對比使用with()函數的篩選方法,就會顯得使用filter()函數更加簡潔清晰。
with(flights,flights[month==7 & day==19 & distance > 800 & (carrier=="AS"|carrier=="HA"),])
3、arrange()函數
?若是依據多列數據進行排序,只需按列的順序寫進此函數中即可;如果是逆序排,只需在變量前面加負號或使用rev()函數即可(注意,逆排序中使用負號的情況僅限于數值變量)
# 依次按month、day、carrier、origin和dest對flights進行排序
head(arrange(flights,-month,-day,carrier,origin,dest))
4、mutate()函數
轉換函數,它可以同時修改和增加若干個變量。與R語言中的內置的轉換函數transform()相比,它的優勢是可在同一段代碼中使用剛建立的新變量。
library(dplyr)
library(nycflights13)
# 計算飛行節約的時間和平均每小時所節約的時間
flights1 <- mutate(flights, gain=arr_delay - dep_delay, gain_per_hour= gain/(air_time/60))
head(flights1$gain)
head(flights1$gain_per_hour)
?5、group_by()和summarise()函數
這兩個函數往往一起使用,先對數據集進行分組,然后再按組進行匯總。
先按照航空公司進行分組:
# 先按航空公司進行分組
flights2 <- group_by(flights, carrier)
# 查看分組變量
group_vars(flights2)
# 查看各組的行數
group_size(flights2)
?然后對各航空公司數據進行匯總:
flights3 <- summarise(flights2, dep_delay_mean = mean(dep_delay, na.rm=T),arr_delay_mean = mean(arr_delay, na.rm=T),distance_sd = sd(distance, na.rm=T))
flights3
6、連接函數
inner_join()函數:用于內連接
left_join()函數:用于左連接
right_join()函數:用于右連接
full_join()函數:用于全連接
7、抽樣函數
sample_n()函數:隨機選出指定個數(樣本容量)的樣本數;
sample_frac()函數:隨機選出指定百分比的樣本數。
sample_n(flights,size=8)sample_frac(flights,size=0.10)
8、管道函數%>%
此函數可以通過不斷地疊加,減少代碼量和中間變量,這種寫法極大地提高了代碼的可讀性和可維護性,特別是在進行數據分析和處理數據框(data frames)時。
在疊加過程中,%>%左邊的結果將作為右邊函數的第一個參數。
dplyr
包中的%>%
操作符實際上是從magrittr
包中借用的,但dplyr
作為數據操作的一個核心包,使得這個操作符在數據科學社區中變得非常流行。
df <- data.frame(id = 1:5,name = c("Alice", "Bob", "Charlie", "David", "Eva"),score = c(85, 90, 95, 88, 92)
)# 使用%>%管道函數
filtered_sorted_df <- df %>%filter(score > 90) %>% # 過濾出score大于90的行arrange(desc(score)) %>% # 按score降序排列select(name, score) # 選擇name和score列print(filtered_sorted_df)
%>%
管道函數可以與dplyr
包中的其他函數(如mutate
、summarise
、group_by
等)結合使用:
flights4 <- flights %>%sample_frac(size = 0.1) %>% # 隨機抽取10%的樣本select(one_of("carrier","month","day","dep_delay","arr_delay","air_time","distance")) %>% # 篩選carrier、month、day等幾列變量mutate(gain = arr_delay - dep_delay,gain_per_hour = gain / (air_time / 60)) %>% # 計算飛行節約時間和平均每小時所節約的時間group_by(carrier,month) %>% # 按航空公司和月份summarise(gain = mean(gain,na.rm = TRUE),distance = mean(distance,na.rm =TRUE)) # 求gain和distance平均值flights4