
終于安排上了時(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+“減號(hào)”;管道符%>%Ctrl+Shift+M
第五章,探索性數(shù)據(jù)分析 exploratory data analysis(EDA)
變動(dòng):是一個(gè)變量?jī)?nèi)部的行為,每次測(cè)量時(shí)數(shù)據(jù)值的變化趨勢(shì)。
相關(guān)變動(dòng):兩個(gè)或多個(gè)變量以相關(guān)的方式共同變化所表現(xiàn)出的趨勢(shì)。多個(gè)變量之間的行為。
模式:如果兩個(gè)變量之間存在系統(tǒng)性的關(guān)系,那么這種關(guān)系就會(huì)再數(shù)據(jù)中表示一種模式。
5.3 變動(dòng):
一維數(shù)據(jù)的表示:geom_bar(binwidth=1)可以對(duì)一維連續(xù)變量進(jìn)行分箱,然后使用條形的高度表示落入箱中的數(shù)量。并且對(duì)于geom_bar(),geom_histogram()可以利用geom_freqpoly()替代,此為疊加的折線圖,并可以在折線圖內(nèi)aes(color= *)參數(shù)映射其它數(shù)據(jù)。
異常值:可用圖層coord_cartesian(ylim=c(0,50))濾出(不顯示,但會(huì)保留)大于此取值的,而不是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 變動(dòng),分布進(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)變動(dòng):
- 分類變量與連續(xù)變量:
- 對(duì)
geom_freqpoly(aes(color=cut)),對(duì)一維的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) 對(duì)分類變量進(jìn)行排序。
- 對(duì)
- 兩個(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è)置透明度。
- 對(duì)連續(xù)變量數(shù)據(jù)進(jìn)行分箱,
geom_bin2d,geom_hex()可以正方形和六邊形分享。
5.6 模式和模型:如果兩個(gè)變量之間存在系統(tǒng)性的關(guān)系,那么這種關(guān)系就會(huì)再數(shù)據(jù)中表示一種模式。
- 變動(dòng)會(huì)生成不確定性,那么相關(guān)變動(dòng)就是減少不確定性,如果兩個(gè)變量是存在系統(tǒng)性的關(guān)系的,那么就可以通過一個(gè)變量的值來預(yù)測(cè)另一個(gè)變量的值。
- 模型:就是抽取模式的一種工具,找到兩個(gè)變量間系統(tǒng)性關(guān)系的方法。
# 5.5 相關(guān)變動(dòng):兩個(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() ## 對(duì)連續(xù)變量的數(shù)據(jù)做分箱處理。
geom_hex()
diamonds %>% ggplot(aes(carat,price))+geom_hex()
第七章. tibble表
是對(duì)傳統(tǒng)R中的data.frame的升級(jí)版替換。
- tibble在打印大數(shù)據(jù)時(shí)會(huì)默認(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")來對(duì)列進(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可以對(duì)人類使用的所有字符進(jìn)行編碼,ASCII為美國(guó)信息交換標(biāo)準(zhǔn)代碼。
- 因子:表示 已知集合的分類變量
- 日期時(shí)間等
8.4 解析文件:readr會(huì)通過文件的前1000行以啟發(fā)式算法guess_parser()返回readr最可信的猜測(cè),接著用parse_guess()使用這個(gè)猜測(cè)來解析列。
8.5 寫入文件和其它導(dǎo)入文件:
- 通過
write_csv,write_tsv,其會(huì)自動(dòng)使用UTF-8對(duì)字符串編碼。 -
write_excel_csv()函數(shù)導(dǎo)為Excel文件。 -
readxl可以讀取EXCEL文件 -
haven讀取SPSS,SAS數(shù)據(jù) -
DBI可對(duì)RMySQL等數(shù)據(jù)庫(kù)查詢 -
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ù)。
- 集合操作:將觀測(cè)作為集合元素來處理。
基本數(shù)據(jù)的準(zhǔn)備包括nycflights13包中的幾個(gè)表。airlines/airports/planes/weather等。
9.3 鍵:唯一標(biāo)識(shí)觀測(cè)的變量
- 主鍵:唯一標(biāo)識(shí) 其所在數(shù)據(jù)表中的觀測(cè)。
- 外鍵:唯一標(biāo)識(shí) 另一個(gè)數(shù)據(jù)表中的觀測(cè)。
- 代理鍵:當(dāng)一張表沒有主鍵,需要使用
mutate()函數(shù)和row_number()函數(shù)為表加上一個(gè)主鍵。 - 理解不同數(shù)據(jù)表之間的關(guān)系的關(guān)鍵時(shí):記住每種關(guān)系只與兩張表有關(guān),不需要清楚所有的事情,只需要明白所關(guān)心的表格即可。
9.4 合并連接:通過兩個(gè)表中的鍵(變量們)來匹配觀測(cè)(行數(shù)值),再將一個(gè)表中的變量復(fù)制到另一個(gè)表格中。 對(duì)比cheatsheet中的信息
-
內(nèi)連接:相當(dāng)于連取交集。將兩個(gè)表中的相等的鍵值取出來。
X %>% inner_join(y,by="key") -
外連接:至少保留存在于一個(gè)表中的觀測(cè)。在另一個(gè)表中未匹配的變量會(huì)以
NA表示。left_join()right_join()full_join()
- 重復(fù)鍵:一對(duì)多(),多對(duì)一,以及多對(duì)多的關(guān)系(兩表中都不唯一,會(huì)以笛卡爾積分的方式呈現(xiàn))。
- 定義兩個(gè)表中匹配的鍵:
- by=NULL,默認(rèn),使用存在于兩個(gè)表中的所有變量。
left_join(x,y,by="weather")left_join(x,y,c("dest"="faa "))
9.5 篩選連接:根據(jù)鍵來對(duì)觀測(cè)數(shù)值進(jìn)行篩選
- semi_join(x,y):保留x表中 與 y表中的觀測(cè)數(shù)值相匹配的數(shù)據(jù)。
- anti_join(x,y):丟棄x表中 與y表中觀測(cè)(行)數(shù)據(jù)相匹配的數(shù)據(jù)。
9.6整理數(shù)據(jù)時(shí)需要對(duì)數(shù)據(jù)進(jìn)行整理:
- 需要找出每個(gè)表中可以作為主鍵的變量。應(yīng)基于數(shù)據(jù)的真實(shí)含義來找主鍵
- 確保主鍵中的每個(gè)變量沒有缺失值,如果有缺失值則不能被識(shí)別!
- 檢查主鍵是否可以與另一個(gè)表中的外鍵相匹配。利用
anti_join()來確定。
9.7集合的操作:
-
intersect(x,y)兩個(gè)表中皆存在。 -
union():返回x表中與y表中的唯一觀測(cè)。 -
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è)觀測(cè)(observation)只有一行;
- 每個(gè)數(shù)據(jù)僅有一個(gè)位置cell。
整理數(shù)據(jù)表,應(yīng)對(duì)一個(gè)變量對(duì)應(yīng)多行 or 一個(gè)觀測(cè)對(duì)應(yīng)多行的問題。利用gather,spread()
-
gather():對(duì)于table4a來說,其存在兩列1999/2000對(duì)應(yīng)相同的變量值。故需要合并,合并后的兩列重新起名字,根據(jù)key="",和value=""。gather(1999,2000,key="year",value="cases")
-
spread():對(duì)于table2來說,存在冗余。需要拆分出多個(gè)變量spread(table2,key=type,value=count)
-
separate():對(duì)于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():對(duì)指定兩列合并處理。- unite(new,centry,year,sep="")
-
rename(),rename_all(): 對(duì)variables變量進(jìn)行重命名。通過library(stringr)。rename_all(tolower) %>% rename_all(~str_replace_all(., "\\.", "_"))
-
mutate(),mutate_all():對(duì)所有的value進(jìn)行重命名,修改名稱mutate_all(tolower) %>% mutate_all(~str_replace_all(., " ", "_"))
-
rowwise(),對(duì)每行的數(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)