R4DS:在線電子書用于學(xué)習(xí)tidyverse的用法
數(shù)據(jù)科學(xué)處理使用tidyverse
data.table
大數(shù)據(jù)處理首選data.table,多CPU并行運(yùn)算,100G內(nèi)存即可支持20億行的基準(zhǔn)測試豪硅。速度讀取寫入速度都比dplyr快鳖目。
R和python的數(shù)據(jù)處理包的速度對比評測
性能評測一般是:group_by和join函數(shù),顯然data.table速度快于dplyr.
dplyr data.table
dplyr data.table對比
tidyverse
包含多個(gè)包
-ggplot2 用于可視化
-dplyr 數(shù)據(jù)處理
-tidyr 數(shù)據(jù)處理
-stringr 字符串的處理
-readr 文件的讀取
-purrr 函數(shù)的迭代
-forcats 處理因子問題
-tibble 實(shí)現(xiàn)data.table類似的優(yōu)雅處理dataframe問題
dplyr參考
數(shù)據(jù)處理經(jīng)常用到的包
dplyr
,data.table
,Base R
測試表明掀亥,dplyr的速度要快于data.table.
dplyr
是tidyverse
其中的一個(gè)包晰韵。
數(shù)據(jù)處理一般的流程:
1.數(shù)據(jù)過濾(去重)
2.選擇
3.比對惹挟,匹配
4.分組
5.排序
6.抽樣
在excel中也可以完成上述操作,但是當(dāng)數(shù)量達(dá)到十萬以上級別后气筋,excel速度慢如蝸牛拆内。
dplyr用法示例
數(shù)據(jù)去重
distinct(df,V1,V2)
根據(jù)V1和V2兩個(gè)條件來進(jìn)行去重
新增列
mutate(df,vnew1=v1-v2,vnew2=vnew1+v3)
支持在創(chuàng)建的新列的基礎(chǔ)上,再新建列宠默。
過濾函數(shù)
filter(df,cond1,cond2,…)
用逗號,隔開表示條件是and的關(guān)系
filter(df,cond1|cond2|…)
用豎線|隔開表示條件是or的關(guān)系
slice(df,80:100)
選取索引80到100的數(shù)據(jù)
排序
arrange(df,V1,desc(V2),V3)
V1,V3升序麸恍,V2降序
arranage(df,V1)
升序排列V1
arrange(df,desc(V3))
降序排列V3
選擇
select(df,V1,V2,V3)
選擇V1,V2,V3這三列
select(df,V1:V3)
選擇V1到V3列之間的所有列
select(df,-c(v1,V3))
選擇除V1,V3之外的所有列
分組
group_by(df,V1,V2)
df根據(jù)V1,V2進(jìn)行分組
計(jì)算統(tǒng)計(jì)數(shù)據(jù)
summarise(df,mean(V1),sum(V4))
隨機(jī)抽取
sample_n(df,1000)
隨機(jī)抽取1000個(gè)數(shù)據(jù)
sample_frac(df,0.7)
隨機(jī)抽取70%的數(shù)據(jù)
參考地址https://www.cnblogs.com/nxld/p/6060533.html
數(shù)據(jù)格式轉(zhuǎn)換tidyr包
library(tidyr)
library(dplyr)
- 缺失值的簡單補(bǔ)齊
- 長形表變寬形表與寬形表變長形表
gather-把寬度較大的數(shù)據(jù)轉(zhuǎn)換成一個(gè)更長的形式,它類比于從reshape2包中融合函數(shù)的功能
spread-把長的數(shù)據(jù)轉(zhuǎn)換成一個(gè)更寬的形式搀矫,它類比于從reshape2包中鑄造函數(shù)的功能抹沪。
gather()相反的是spread(),前者將不同的列堆疊起來瓤球,后者將同一列分開
- 長形表變寬形表與寬形表變長形表
長短數(shù)據(jù)的轉(zhuǎn)換主要是用于ggplot2的出圖融欧,ggplot2需要的是長數(shù)據(jù),而我們?nèi)粘]斎氲臄?shù)據(jù)是寬數(shù)據(jù)
寬數(shù)據(jù)實(shí)例
下面數(shù)據(jù)的第一列數(shù)字是R中的行號
allinfo
內(nèi)容如下
province primary middle senior higher postgraduate
1 北京 109.4579 110.5105 96.20949 98.91572 107.82594
2 天津 113.4776 114.0266 94.79238 99.90067 88.54674
3 河北 114.6299 113.0214 91.19643 87.67520 81.96543
4 山西 107.9786 108.3219 92.03961 82.94410 73.76735
5 內(nèi)蒙古 109.1339 108.9091 92.13359 89.96668 67.54206
6 遼寧 110.3081 110.8525 91.70425 112.46839 87.90451
allinfoNew
內(nèi)容如下
轉(zhuǎn)換成長數(shù)據(jù)后
allinfoNew <- allinfo %>% gather(school,value, -province)
將allinfo的所有列卦羡,除了province列之外全部合并成兩列噪馏,一列是school,一列是value.
province school value
1 北京 primary 109.45794
2 天津 primary 113.47760
3 河北 primary 114.62993
4 山西 primary 107.97863
5 內(nèi)蒙古 primary 109.13391
6 遼寧 primary 110.30810
7 北京 middle 110.51045
8 天津 middle 114.02665
9 河北 middle 113.02139
10 山西 middle 108.32195
11 內(nèi)蒙古 middle 108.90907
12 遼寧 middle 110.85252
13 北京 senior 96.20949
14 天津 senior 94.79238
15 河北 senior 91.19643
16 山西 senior 92.03961
17 內(nèi)蒙古 senior 92.13359
18 遼寧 senior 91.70425
19 北京 higher 98.91572
20 天津 higher 99.90067
21 河北 higher 87.67520
22 山西 higher 82.94410
23 內(nèi)蒙古 higher 89.96668
24 遼寧 higher 112.46839
25 北京 postgraduate 107.82594
26 天津 postgraduate 88.54674
27 河北 postgraduate 81.96543
28 山西 postgraduate 73.76735
29 內(nèi)蒙古 postgraduate 67.54206
30 遼寧 postgraduate 87.90451
長數(shù)據(jù)轉(zhuǎn)為寬數(shù)據(jù)
allinfoFat <- allinfoNew %>% spread(school,value)
allinfoFat
和allinfo的內(nèi)容一致。
school是要拆分的列的對象绿饵,value是要拆分列的值逝薪。
- 列分割與列合并
separate-將一列按分隔符分割為多列
unite-將多列按指定分隔符合并為一列
- 列分割與列合并
tidyr包:(gather(寬數(shù)據(jù)轉(zhuǎn)為長數(shù)據(jù))、spread(長數(shù)據(jù)轉(zhuǎn)為寬數(shù)據(jù))蝴罪、unit(多列合并為一列)董济、separate(將一列分離為多列))
stringr的用法
library(stringr)
x <- c("why", "video", "cross", "extra", "deal", "authority")
str_length(x)#獲取字符串的長度
#> [1] 3 5 5 5 4 9
str_c(x, collapse = ", ")#替換分隔符
#> [1] "why, video, cross, extra, deal, authority"
str_sub(x, 1, 2)#提取指定長度的字符串
#> [1] "wh" "vi" "cr" "ex" "de" "au"
str_subset(x, "[aeiou]") #匹配包含aeiou的字符串
#> [1] "video" "cross" "extra" "deal" "authority"
str_count(x, "[aeiou]")#匹配包含aeiou的字符的數(shù)量
#> [1] 0 3 1 2 2 4
str_detect(x, "[aeiou]") #返回是否包含aeiou字符串的邏輯值
#> [1] FALSE TRUE TRUE TRUE TRUE TRUE
str_locate(x, "[aeiou]") #返回每個(gè)字符串首次匹配的起始位置和終止位置。(例子中需要匹配的字符串長度都是1要门,所以終止位置和起始位置是一樣的)
str_locate_all(x, "[aeiou]") #返回每個(gè)字符串所有的與匹配字符匹配的起始位置和終止位置虏肾。
str_extract(x, "[aeiou]") #提取每個(gè)字符串中與匹配字符串一致的字符
str_match(x, "(.)[aeiou](.)") #匹配
str_replace(x, "[aeiou]", "^") #替換匹配的字符
#[1] "why" "v^deo" "cr^ss" "^xtra" "d^al" "^uthority"
str_split(c("a,b", "c,d,e"), ",") #指定使用逗號分割字符串
forcats的 用法
library(forcats)
fct_reorder()#: 按另一個(gè)變量重新排序一個(gè)因子。
fct_infreq()#:按值的頻率對因子重新排序欢搜。
fct_relevel()#:手動(dòng)更改因子的順序封豪。
fct_lump()#:將一個(gè)因素的最少/最頻繁值折疊為“其他”。
starwars %>%
filter(!is.na(species)) %>%
count(species, sort = TRUE)
starwars %>%
filter(!is.na(species)) %>%
mutate(species = fct_lump(species, n = 3)) %>%
count(species)
filter(starwars,!is.na(hair_color))%>%
ggplot(aes(x = hair_color)) +
geom_bar() +
coord_flip()
starwars %>%
filter(!is.na(hair_color))%>%
mutate(hair_color = fct_infreq(hair_color))%>%
ggplot(aes(x = hair_color)) +
geom_bar() +
coord_flip()
readr讀取文件
readr
比baseR讀取快10倍
data.table
包的fread
的速度比readr
快1-2倍
library(readr)
read_csv()#: 逗號分隔 (CSV) 文件
read_tsv()#: 制表符分隔的文件
read_delim()#: 一般分隔文件
read_fwf()#: 固定寬度文件
read_table()#:列由空格分隔的表格文件炒瘟。
read_log()#: 網(wǎng)絡(luò)日志文件
purrr用于迭代函數(shù)吹埠,速度非常快
library(purrr)
#purrr的所有函數(shù)是C實(shí)現(xiàn)的,所以速度非吃道牛快粘都。map實(shí)現(xiàn)的是for循環(huán),返回值是向量
map() #map的第一個(gè)參數(shù)可以是向量或數(shù)據(jù)框刷袍。
map_lgl() #生成一個(gè)邏輯向量翩隧。
map_int() #生成一個(gè)整數(shù)向量。
map_dbl() #形成一個(gè)雙向量呻纹。
map_chr() #制作一個(gè)字符向量堆生。
#示例:
map_int(x,str_count)
x1 <- rnorm(100,mean = 50,sd=15) #產(chǎn)生隨機(jī)數(shù)100個(gè),均值50雷酪,標(biāo)準(zhǔn)差15
x2 <- rnorm(100,mean=100)
x3 <- rnorm(100)
xd <- data.frame(x1,x2,x3)
map(xd,sum)
map(xd,sd)
dplyr包的使用:數(shù)據(jù)處理
library(dplyr)
##數(shù)據(jù)包 航班 世界發(fā)展 棒球數(shù)據(jù)
if(!require(c("nycflights13", "gapminder", "Lahman")))install.packages(c("nycflights13", "gapminder", "Lahman")) #三個(gè)數(shù)據(jù)包
library(nycflights13)
flights #是2013年美國紐約出發(fā)的航班信息
#dplyr常用的函數(shù)
#根據(jù)其值(filter())選擇觀察值淑仆。
#重新排序行(arrange())。
#按變量名稱(select())選擇變量哥力。
#使用現(xiàn)有變量(mutate())的功能創(chuàng)建新變量糯景。
#將許多值折疊為一個(gè)摘要(summarise())。
April_1st <- filter(flights,month==4,day==1) #查詢2013年4月1日出發(fā)的航班
filter(flights,!(dep_delay>60|arr_delay>60),month %in% c(4,5,6)) #查看第二季度的出發(fā)和到達(dá)時(shí)間延誤均小于等于60min的航班
#查找早上7點(diǎn)前到達(dá)和23點(diǎn)之后到達(dá)的航班省骂,根據(jù)出發(fā)時(shí)間從早到晚蟀淮,和到達(dá)時(shí)間從晚到早排序
filter(flights,arr_time<700 | arr_time>2300) %>% arrange(dep_time,desc(arr_time))
##挑選指定列
select(flights,origin,dest,distance,air_time)
#挑選指定列和指定列之間的列
select(flights, flight:hour)
#挑選除了指定列和指定列之間的列之外所有的列
select(flights, -(flight:hour))
#挑選指定列之外的列
select(flights,-c(year,month,day))
#重命名列名(新的列名在前面,=后是舊的列名)
rename(flights, departtime = dep_time)
#select內(nèi)部輔助函數(shù)
# starts_with("abc"):匹配以“ abc”開頭的名稱钞澳。
# ends_with("xyz"):匹配以“ xyz”結(jié)尾的名稱怠惶。
# contains("ijk"):匹配包含“ ijk”的名稱。
# matches("(.)\\1"):選擇與正則表達(dá)式匹配的變量轧粟。該變量與任何包含重復(fù)字符的變量匹配策治。您將了解有關(guān)字符串中的正則表達(dá)式的更多信息。
# num_range("x", 1:3):匹配x1兰吟,x2和x3通惫。
#挑選列名以time結(jié)尾的列
select(flights,ends_with("time"))
#挑選包含dep起飛信息的列
select(flights,contains("dep"))
#select和everything聯(lián)用,用于調(diào)整列的順序(把origin和dest拍到最前面)
select(flights, origin, dest, everything())
#select選擇合適的列
flights_sml <- select(flights,
year:day,
ends_with("delay"),
distance,
air_time
)
head(flights_sml)
#mutate增加新的列混蔼,同時(shí)保留原來的列
mutate(flights_sml,
gain = dep_delay - arr_delay,
speed = distance / air_time * 60
)
#transmute是生成新的列履腋,但是不保留原來的列
transmute(flights,
gain = dep_delay - arr_delay,
hours = air_time / 60,
gain_per_hour = gain / hours
)
#near 判斷兩個(gè)數(shù)字是否相等
##因?yàn)橛?jì)算機(jī)有效數(shù)字的問題,無限不循環(huán)小數(shù)會(huì)被截?cái)嗖严杂袝r(shí)候==并不成立
sqrt(2)^2 == 2 #返回FALSE
near(sqrt(2)^2,2) #返回TRUE
#lead/lag前導(dǎo)值或滯后值
#滾動(dòng)分析
x <- seq(1,29,by=3)
x
cumsum(x)
#> [1] 1 5 12 22 35 51 70 92 117 145
cummean(x)
#[1] 1.0 2.5 4.0 5.5 7.0 8.5 10.0 11.5 13.0 14.5
cumprod(x)
cummax(x)
cummin(x)
#分析航班的(到達(dá)時(shí)間-出發(fā)時(shí)間)和空中時(shí)間的差值遵湖,可以看出非飛行時(shí)間在機(jī)艙內(nèi)的
### 時(shí)間比較長的航班都是長距離航班>1000km,而且主要是目的地是JFK機(jī)場的航班。說明JFK的進(jìn)港時(shí)間比較長晚吞,機(jī)場地勤比較慢
flights %>% arrange(origin) %>% group_by(origin) %>%
select(contains("time"),dest,distance) %>%
mutate(groundtime = arr_time - dep_time - air_time) %>%
arrange(desc(groundtime))
flights %>% head(10) %>%
identity() %>% rownames()
ggplot(aes(x=air_time))+
#geom_histogram()+
NULL
geom_boxplot(aes(carrier,flight))
#summaries
summarise(flights,delay=mean(dep_delay,na.rm=TRUE))
#顯示出每天的平均出發(fā)延誤時(shí)長
by_day <- group_by(flights,year,month,day)
summarise(by_day,delay = mean(dep_delay,na.rm=TRUE))
#顯示出發(fā)地和到達(dá)地的平均延誤時(shí)長
by_port <- group_by(flights,origin,dest)
summarise(by_port,delay=mean(dep_delay,na.rm=TRUE))
by_dest <- group_by(flights, dest) #根據(jù)出發(fā)地分組
delay <- summarise(by_dest,
count = n(),
dist = mean(distance, na.rm = TRUE), #距離的均值
delay = mean(arr_delay, na.rm = TRUE) #到達(dá)時(shí)延誤的均值
) %>% filter(count > 20, dest != "HNL") #過濾掉計(jì)數(shù)少于20延旧,目的地是HNL的數(shù)據(jù),HNL距離其他機(jī)場太遠(yuǎn)了
# It looks like delays increase with distance up to ~750 miles
# and then decrease. Maybe as flights get longer there's more
# ability to make up delays in the air?
ggplot(data = delay, mapping = aes(x = dist, y = delay)) +
geom_point(aes(size = count), alpha = 1/3) +
geom_smooth(se = FALSE)
#> `geom_smooth()` using method = 'loess' and formula 'y ~ x'
na.rm = TRUE #是刪除含有NA的行
##包含NA的表示航班取消槽地,第一步先過濾掉這部分航班
normal_flight <- flights %>% filter(!is.na(dep_delay),!is.na(arr_delay))
delays <- normal_flight %>%
group_by(tailnum) %>%
summarise(delay=mean(arr_delay))
ggplot(data=delays,mapping = aes(x=delay))+geom_freqpoly(binwidth = 10)
##filter是過濾
##arrange是排序迁沫,arrange(desc(air_time)) desc是倒序