終于安排上了時(shí)間再把《R數(shù)據(jù)科學(xué)》這本書學(xué)習(xí)了一遍亲配。以下是學(xué)習(xí)的過程中的一些參考資料唱捣,分享一下忌穿。
- 英文原版在線https://r4ds.had.co.nz/index.html
- 中文翻譯版已有售萨惑,建議紙質(zhì)版書籍隨時(shí)翻翻更舞。電子版網(wǎng)盤分享 https://pan.baidu.com/s/1fkpqYahQHPkwx66XD2gGGg 提取碼: akct
- 最近才公布的課后習(xí)題參考答案https://jrnold.github.io/r4ds-exercise-solutions/
- Rstudio的一些便捷CheetSheetshttps://www.rstudio.com/resources/cheatsheets/
- 另外在寫代碼過程中Rstudio操作時(shí)的方便快捷鍵:賦值<-
Alt+“減號”
;管道符%>%Ctrl+Shift+M
第五章拙吉,探索性數(shù)據(jù)分析 exploratory data analysis(EDA)
變動:是一個(gè)變量內(nèi)部的行為潮孽,每次測量時(shí)數(shù)據(jù)值的變化趨勢。
相關(guān)變動:兩個(gè)或多個(gè)變量以相關(guān)的方式共同變化所表現(xiàn)出的趨勢筷黔。多個(gè)變量之間的行為往史。
模式:如果兩個(gè)變量之間存在系統(tǒng)性的關(guān)系,那么這種關(guān)系就會再數(shù)據(jù)中表示一種模式必逆。
5.3 變動:
一維數(shù)據(jù)的表示:geom_bar(binwidth=1)
可以對一維連續(xù)變量進(jìn)行分箱怠堪,然后使用條形的高度表示落入箱中的數(shù)量揽乱。并且對于geom_bar()
,geom_histogram()
可以利用geom_freqpoly()
替代名眉,此為疊加的折線圖,并可以在折線圖內(nèi)aes(color= *)
參數(shù)映射其它數(shù)據(jù)凰棉。
異常值:可用圖層coord_cartesian(ylim=c(0,50))
濾出(不顯示损拢,但會保留)大于此取值的,而不是ylim(0,50)直接丟棄撒犀。
-
將異常值當(dāng)做缺失值處理:利用
mutate()
函數(shù)創(chuàng)建新變量代替原來的變量福压,使用ifelse()函數(shù)將異常值替換為NA:diamons %>% mutate(y = ifelse(y < 3 | y>20, NA, y))
- 計(jì)算畫圖時(shí)以參數(shù)
na.rm=TRUE
過濾掉
- 異常值差異不大的,可以用缺失值來代替或舞,而異常值較大的需要探究其原因荆姆。
## 5.3 變動,分布進(jìn)行可視化表示
ggplot(data = diamonds)+geom_bar(mapping = aes(x=cut))
ggplot(data = diamonds)+geom_bar(mapping = aes(x=carat),binwidth = 0.5)
diamonds %>% filter(carat<3) %>% ggplot(mapping = aes(x=carat))+geom_histogram(binwidth = 0.1)
diamonds %>% filter(carat<3) %>% ggplot(mapping = aes(x=carat))+ geom_freqpoly(aes(color=cut),binwidth=0.1)+scale_color_brewer(palette = "Set1")
### 5.3.3異常值映凳,
ggplot(diamonds)+geom_histogram(mapping = aes(x=y),binwidth = 0.5)+ylim(0,60)
ggplot(diamonds)+geom_histogram(mapping = aes(x=y),binwidth = 0.5)+coord_cartesian(ylim = c(0,60))
# 5.4 異常值,推薦是將異常值改為缺失值處理胆筒。
diamonds %>% filter(between(y,3,20))
#### mutate()創(chuàng)建新變量代替原來的變量
diamonds <- diamonds %>% mutate(y=ifelse(y<3 | y>30,NA,y))
diamonds <- select(diamonds,-(`ifelse(y < 3 | y > 30, NA, y)`))
ggplot(diamonds,aes(x=x,y=y))+geom_point(na.rm = T)
flights %>% mutate(cancelled=is.na(dep_time),sched_hour=sched_dep_time%/%100,sched_min=sched_dep_time%%100,sched_depart_time=sched_hour+sched_min/60) %>% select(sched_hour,sched_min,sched_depart_time,everything()) %>% ggplot(aes(x=sched_depart_time))+geom_freqpoly(aes(color=cancelled),binwidth=1/5)
5.5 相關(guān)變動:
- 分類變量與連續(xù)變量:
- 對
geom_freqpoly(aes(color=cut))
,對一維的count計(jì)數(shù)進(jìn)行標(biāo)準(zhǔn)化可以y=..density..標(biāo)準(zhǔn)化。 - 箱線圖boxplot()標(biāo)準(zhǔn)化:reorder(class,hwy,FUN=median) 對分類變量進(jìn)行排序仆救。
- 對
- 兩個(gè)分類變量:可以利用heatmap圖抒和,geom_tile, geom_count
- geom_count()函數(shù)
- 另外可先count(x,y)計(jì)數(shù),再利用
geom_tile()
和geom_count()
填充圖形屬性彤蔽。
- 兩個(gè)連續(xù)變量:
- 通常的geom_point(),可通過alpha參數(shù)設(shè)置透明度摧莽。
- 對連續(xù)變量數(shù)據(jù)進(jìn)行分箱,
geom_bin2d
,geom_hex()
可以正方形和六邊形分享顿痪。
5.6 模式和模型:如果兩個(gè)變量之間存在系統(tǒng)性的關(guān)系镊辕,那么這種關(guān)系就會再數(shù)據(jù)中表示一種模式。
- 變動會生成不確定性蚁袭,那么相關(guān)變動就是減少不確定性丑蛤,如果兩個(gè)變量是存在系統(tǒng)性的關(guān)系的,那么就可以通過一個(gè)變量的值來預(yù)測另一個(gè)變量的值撕阎。
- 模型:就是抽取模式的一種工具受裹,找到兩個(gè)變量間系統(tǒng)性關(guān)系的方法。
# 5.5 相關(guān)變動:兩個(gè)或者多個(gè)變量間的關(guān)系虏束。
ggplot(diamonds,mapping = aes(x=price))+geom_freqpoly(aes(color=cut),binwidth=500)
ggplot(diamonds)+geom_freqpoly(aes(x=price,y=..density..,color=cut),binwidth=200)+scale_color_brewer(palette = "Set2")
###mpg
ggplot(mpg,mapping = aes(x=class,y=hwy))+geom_boxplot()
ggplot(mpg)+geom_boxplot(mapping = aes(x=reorder(class,hwy,FUN = mean),y=hwy,fill=class))
ggplot(mpg)+geom_boxplot(mapping = aes(x=reorder(class,hwy,FUN=median),y=hwy))+coord_flip()
### 5.5.1分類變量與連續(xù)變量
### 5.5.2倆個(gè)分類變量間的關(guān)系棉饶,geom_tile(aes(fill=count))
ggplot(data = diamonds)+geom_count(mapping = aes(x=cut,y=color))
diamonds %>% count(color,cut) %>% ggplot()+geom_tile(aes(x=color,y=cut,fill=n))
### 5.5.3 兩個(gè)連續(xù)變量
geom_point()
geom_bin2d() ## 對連續(xù)變量的數(shù)據(jù)做分箱處理。
geom_hex()
diamonds %>% ggplot(aes(carat,price))+geom_hex()
第七章. tibble表
是對傳統(tǒng)R中的data.frame的升級版替換镇匀。
- tibble在打印大數(shù)據(jù)時(shí)會默認(rèn)僅顯示10行(observation)照藻,屏幕可顯示的列(variety)
- tibble 是特殊的列表list(list(a=1),list(b=2))
第八章. 使用readr進(jìn)行數(shù)據(jù)的導(dǎo)入
8.1 常用的tidyverse所提供的數(shù)據(jù)導(dǎo)入的方式:
-
read_csv()
:以,分割 -
read_csv2()
:以; 分割 -
read_tsv()
:以\t分割 -
read_delim()
:可以讀取以任意分隔符的文件delim="\t" (delimiter 分界符)
8.2 以read_csv()為例,內(nèi)部提供的函數(shù):
- skip=2汗侵,跳過開頭的n行
- comment="#" 跳過以#開頭的行
- col_names=FALSE 不以第一行作為列標(biāo)題幸缕。也可col_names=c("a","b","c")來對列進(jìn)行命名
- na="." 設(shè)定哪個(gè)值為文件的缺失值
8.3 解析向量:主要依靠parse_*()
函數(shù)族解析,第一個(gè)參數(shù)為需要解析的字符向量晰韵,na參數(shù)設(shè)定 缺失值處理na="."发乔,函數(shù)族包括parse_logical(), parse_double(), character(), factor(), datetime().
- parse_number()可以忽略數(shù)值前后的非數(shù)值型字符,可以處理 貨幣/百分比雪猪,提取嵌在文本中的數(shù)值
- character:UTF-8可以對人類使用的所有字符進(jìn)行編碼栏尚,ASCII為美國信息交換標(biāo)準(zhǔn)代碼。
- 因子:表示 已知集合的分類變量
- 日期時(shí)間等
8.4 解析文件:readr會通過文件的前1000行以啟發(fā)式算法guess_parser()返回readr最可信的猜測只恨,接著用parse_guess()使用這個(gè)猜測來解析列译仗。
8.5 寫入文件和其它導(dǎo)入文件:
- 通過
write_csv
,write_tsv
,其會自動使用UTF-8對字符串編碼官觅。 -
write_excel_csv()
函數(shù)導(dǎo)為Excel文件纵菌。 -
readxl
可以讀取EXCEL文件 -
haven
讀取SPSS,SAS數(shù)據(jù) -
DBI
可對RMySQL等數(shù)據(jù)庫查詢 -
jsonlite
讀取JSON的層次數(shù)據(jù)。 -
xml2
讀取XML文件數(shù)據(jù)
第九章. 使用dplyr處理關(guān)系數(shù)據(jù)休涤,多個(gè)數(shù)據(jù)表咱圆。
綜合多個(gè)表中的數(shù)據(jù)來解決感興趣的問題。存在于多個(gè)表中的數(shù)據(jù)稱為關(guān)系數(shù)據(jù)。且關(guān)系總是定義于兩個(gè)表之間的闷堡。 包括有三類操作處理關(guān)系數(shù)據(jù):
- 合并數(shù)據(jù):在一個(gè)表中添加另一個(gè)表的新變量隘膘,添加新變量的方式是以連接兩個(gè)表的鍵來實(shí)現(xiàn)的。
- 篩選連接:在A表中杠览,根據(jù)鍵是否存在于B表中來篩選這個(gè)A表中的數(shù)據(jù)弯菊。
- 集合操作:將觀測作為集合元素來處理。
基本數(shù)據(jù)的準(zhǔn)備包括nycflights13
包中的幾個(gè)表踱阿。airlines/airports/planes/weather等管钳。
9.3 鍵:唯一標(biāo)識觀測的變量
- 主鍵:唯一標(biāo)識 其所在數(shù)據(jù)表中的觀測。
- 外鍵:唯一標(biāo)識 另一個(gè)數(shù)據(jù)表中的觀測软舌。
- 代理鍵:當(dāng)一張表沒有主鍵才漆,需要使用
mutate()
函數(shù)和row_number()
函數(shù)為表加上一個(gè)主鍵。 - 理解不同數(shù)據(jù)表之間的關(guān)系的關(guān)鍵時(shí):記住每種關(guān)系只與兩張表有關(guān)佛点,不需要清楚所有的事情醇滥,只需要明白所關(guān)心的表格即可。
9.4 合并連接:通過兩個(gè)表中的鍵(變量們)來匹配觀測(行數(shù)值)超营,再將一個(gè)表中的變量復(fù)制到另一個(gè)表格中鸳玩。 對比cheatsheet中的信息
-
內(nèi)連接:相當(dāng)于連取交集。將兩個(gè)表中的相等的鍵值取出來演闭。
X %>% inner_join(y,by="key")
-
外連接:至少保留存在于一個(gè)表中的觀測不跟。在另一個(gè)表中未匹配的變量會以
NA
表示。left_join()
right_join()
full_join()
- 重復(fù)鍵:一對多()米碰,多對一窝革,以及多對多的關(guān)系(兩表中都不唯一,會以笛卡爾積分的方式呈現(xiàn))吕座。
- 定義兩個(gè)表中匹配的鍵:
- by=NULL虐译,默認(rèn),使用存在于兩個(gè)表中的所有變量米诉。
left_join(x,y,by="weather")
left_join(x,y,c("dest"="faa "))
9.5 篩選連接:根據(jù)鍵來對觀測數(shù)值進(jìn)行篩選
- semi_join(x,y):保留x表中 與 y表中的觀測數(shù)值相匹配的數(shù)據(jù)菱蔬。
- anti_join(x,y):丟棄x表中 與y表中觀測(行)數(shù)據(jù)相匹配的數(shù)據(jù)。
9.6整理數(shù)據(jù)時(shí)需要對數(shù)據(jù)進(jìn)行整理:
- 需要找出每個(gè)表中可以作為主鍵的變量史侣。應(yīng)基于數(shù)據(jù)的真實(shí)含義來找主鍵
- 確保主鍵中的每個(gè)變量沒有缺失值,如果有缺失值則不能被識別魏身!
- 檢查主鍵是否可以與另一個(gè)表中的外鍵相匹配惊橱。利用
anti_join()
來確定。
9.7集合的操作:
-
intersect(x,y)
兩個(gè)表中皆存在箭昵。 -
union()
:返回x表中與y表中的唯一觀測税朴。 -
setdiff()
:在x表中,但不在y表中的數(shù)值。
library(tidyverse)
library(nycflights13)
planes;airports;airlines;weather;
## 9.3鍵
weather %>% count(year,month,day,hour,origin) %>% filter(n>1) ### 篩選唯一的鍵
## 9.4 合并連接
flights2 <- flights %>% select(year:day,hour,origin,dest,tailnum,carrier)
flights2 %>% select(-(hour:origin)) %>% left_join(airlines,by = "carrier")
flights2 %>% select(-(hour:origin)) %>% right_join(airlines,by = "carrier")
flights2 %>% left_join(weather) ## 自然連接,使用存在于兩個(gè)表中的所有變量正林。
flights2 %>% left_join(planes,by = "tailnum") ## 共有的
flights2 %>% left_join(airports,c("origin" = "faa"))
### exercise
##9.4.6-1目的地的平均延誤時(shí)間泡一,與空間分布。
flights %>% group_by(dest) %>% summarise(dest_delay=mean(arr_delay,na.rm = T)) %>% left_join(airports,c("dest"="faa")) %>% filter(dest_delay>0)%>%ggplot(aes(lon,lat))+borders("state")+geom_point(aes(size=dest_delay))
airports %>% semi_join(flights,c("faa"="dest")) %>% ggplot(aes(lon,lat))+borders("state")+geom_point()
##exercise3 飛機(jī)的機(jī)齡與延誤時(shí)間
flights %>% group_by(tailnum) %>% summarise(count=n(),delay_tailnum=mean(arr_delay,na.rm = T)) %>% left_join(planes,by="tailnum") %>% filter(!is.na(year)) %>% ggplot(aes(x=delay_tailnum))+geom_freqpoly(aes(color=year),binwidth=1)
###geom_ribbon作圖
## 9.5 篩選連接
(top_dest <- flights %>% count(dest,sort = T) %>% head(10))
flights %>% filter(dest %in% top_dest$dest)
flights %>% semi_join(top_dest,by = "dest")
使用tidyr整理數(shù)據(jù)表 Tidy data
這一章在中文版里并沒有觅廓,所以跟著英文在線版的學(xué)鼻忠。
整潔的數(shù)據(jù)基本準(zhǔn)則(以tidyr內(nèi)部數(shù)據(jù)table1,table2,table3,table4a,table4b)為例:
- 每個(gè)變量(variables)都只有一列;
- 每個(gè)觀測(observation)只有一行杈绸;
- 每個(gè)數(shù)據(jù)僅有一個(gè)位置cell帖蔓。
整理數(shù)據(jù)表,應(yīng)對一個(gè)變量對應(yīng)多行 or 一個(gè)觀測對應(yīng)多行的問題瞳脓。利用gather
塑娇,spread()
-
gather()
:對于table4a來說,其存在兩列1999/2000對應(yīng)相同的變量值劫侧。故需要合并埋酬,合并后的兩列重新起名字,根據(jù)key=""
烧栋,和value=""
奇瘦。gather(1999,2000,key="year",value="cases")
-
spread()
:對于table2來說,存在冗余劲弦。需要拆分出多個(gè)變量spread(table2,key=type,value=count)
-
separate()
:對于table3來說耳标,rate一列數(shù)據(jù)可以拆分。separate(table3,rate,into=c("cases","population"))
-
sep=
參數(shù)默認(rèn)是以非數(shù)字 非字母的字符為分隔符邑跪,也可以指定分隔符根據(jù)正則匹配次坡。sep=4表示以4個(gè)字符作為分隔符。 -
convert = TRUE
表示改變分割后的數(shù)據(jù)結(jié)構(gòu)画畅。
-
unite()
:對指定兩列合并處理砸琅。- unite(new,centry,year,sep="")
-
rename()
,rename_all()
: 對variables變量進(jìn)行重命名轴踱。通過library(stringr)症脂。rename_all(tolower) %>% rename_all(~str_replace_all(., "\\.", "_"))
-
mutate()
,mutate_all()
:對所有的value進(jìn)行重命名淫僻,修改名稱mutate_all(tolower) %>% mutate_all(~str_replace_all(., " ", "_"))
-
rowwise()
诱篷,對每行的數(shù)據(jù)進(jìn)行處理,加和/平均值處理雳灵。iris %>% select(contains("Length")) %>% rowwise() %>% mutate(avg_length = mean(c(Petal.Length, Sepal.Length)))
## 1 tidy_data
#### compare different dataset
table1
table2
table3
table4a;table4b
table1 %>% mutate(rate=cases/population *10000)
table1 %>% count(year,wt=cases)
ggplot(table1,aes(year,cases)) + geom_line(aes(color=country))+geom_point(color="grey")
## 2 gather()
table4a
table4a %>% gather(`1999`,`2000`,key = "year",value = "cases")
table4b %>% gather(`1999`,`2000`,key="year",value="population")
left_join(table4a,table4b,by=c("country","year"))
## 3 spread()
table2
table2 %>% spread(key = type,value = count)
stocks <- tibble(
year=c(2015,2015,2016,2016),
half=c(1,2,1,2),
return=c(1.88,0.59,0.92,0.17)
)
stocks
stocks %>% spread(year,return) %>% gather("year","return",`2015`,`2016`)
## 綜合操作
who %>%
gather(new_sp_m014:newrel_f65,key="key",value="count",na.rm = T) %>%
mutate(key=str_replace(key,"newrel","new_rel")) %>%
separate(key,into = c("new","var","sexage"),sep="_") %>%
select(-iso2,-iso3,-new) %>%
separate(sexage,into = c("sex","age"),sep=1)