Introduction to Programming and Data Science with R
week 6 Shu-Kai Hsieh
2021-03-25
在了解基本的 R
語法之後,我們要進入整頓資料 (data wrangling/transformation)(進而理解資料)的學習階段。
幸福的人都很類似,不幸的人則各有各的不幸。 – Лев Николаевич Толстой
首先你會拿到資料,但是不整齊 (non-tidy) 的資料讓妳的人生被浪費。
Tidy datasets are all alike, but every messy dataset is messy in its own way.” –– Hadley Wickham
那整齊的資料是什麼意思?(不是不乾淨)
三原則
目前大家學習了 R 語言的基本語法:從變數、資料類型、資料結構、流程控制、迴圈與自訂函數、輸入輸出等等。接著可以開始針對要處理的問題,進一步學習資料整頓、視覺化、統計與機器學習等應用。
近年來由主要由 Rtudio
開發團隊則推出一個整體架構 tidyverse,希望形成一個資料科學的套件生態圈,共享處理資料的哲學、語法、與資料結構。 目的之一是希望能在最短時間讓初學者直接切入資料處理與視覺化的專案應用,讓 R 語言能夠很快地直接派上用場。 這個想法甚至引發了 R 語言教育的路線之爭 (R base first vs Tidyverse first
)。
我們先掌握兩個核心的套件架構即可。
dplyr
: a Grammar of Data Manipulationggplot2
: a Grammar of Graphics在 DataCamp 上的 Introduction to the Tidyverse
的課程,課程時數約四小時,請大家可找時間練習。
dplyr
: a grammar for data wrangling先看一下網站簡介 並安裝
可以開始利用 cheatsheet 來參考 (上傳品質很好的文本處理 cheatsheet 或 R package 也可以當成期末專案)
Data manipulation with five verbs :filter()
, select()
, arrange()
, mutate()
, summarise()
。 注意:直行(VAR)橫列 (OBS)
篩選 filter()
: take a subset of the rows (i.e., observations, OBS)
按給定的邏輯判斷,篩選出符合要求的 OBS, 類似於 subset()
。
選擇 select()
: take a subset of the columns (i.e., variables, VAR)
用 VAR 作參數來選擇 OBS。
排列 arrange()
: sort the rows
按給定的 VAR 依次對 OBS 進行排序。類似於 order()
。
增行 mutate()
: add or modify existing columns
對已有 VAR 進行運算並添加為新的 VAR。類似於 transform()
。
摘要 summarise()
: aggregate the data across rows
對data frame 調用其它函數進行 summarise, 並回傳一維結果。
使用方法:Each of these functions takes a data frame as its first argument, and returns a data frame. First argument is a data frame, and subsequent arguments say what to do with data frame.
%>%
infix operator (which can be pronounced as 「then」)# The easiest way to get dplyr is to install the whole tidyverse:
#install.packages("tidyverse")
library(tidyverse)
# play with the starwars data
# head(starswar)
# filter
starwars %>%
filter(species == "Droid")
# select
starwars %>%
select(name, ends_with("color"))
# mutate then select
starwars %>%
mutate(name, bmi = mass / ((height / 100) ^ 2)) %>%
select(name:mass, bmi)
# arrange
starwars %>%
arrange(desc(mass))
group_by()
這個概念結合起來時非常強大!# group_by then summarise then filter
starwars %>%
group_by(species) %>%
summarise(
n = n(), # number of values in a vector
mass = mean(mass, na.rm = TRUE)
) %>%
filter(
n > 1,
mass > 50
)
starwars %>% select(species) %>%
filter(species=="Droid" | species=="Human") %>%
group_by(species) %>%
summarize(n=n())
unlist()
,unique()
)starwars %>%
select(films) %>%
unlist() %>%
unique()
starwars %>%
filter(name=="Luke Skywalker") %>%
select(films) %>%
unlist()
base R
approch 和 tidyverse
approachfilter
(keep rows marching criteria) : 篩選觀察
filter(df, 回傳符合邏輯條件的 rows)
# base R approach
#starwars[starwars$height > 160 & starwars$sex == "female", ]
# dplyr approach
# note: you can use comma or ampersand to represent AND condition
filter(starwars, height > 160 & sex == "female")
select
: Pick columns by name 選取變量
# base R approach to select DepTime, ArrTime, and FlightNum columns
#starwars[, c("name", "height", "gender")]
# dplyr approach
select(starwars, name, height, gender)
# use colon to select multiple contiguous columns, and use `contains` to match columns by name
# note: `starts_with`, `ends_with`, and `matches` (for regular expressions) can also be used to match columns by name
# 或者使用 - 來排除某列
select(starwars, name:gender, contains("color"))
# nesting method to select name and height columns and filter for height > 90
#filter(select(starwars, name, height), height > 90)
# chaining method
starwars %>%
select(name, height) %>%
filter(height > 90)
rename()
重命名變量 variable names: rename(tbl, newname = oldname,...)
min_rank()
), offset functions (lead()
and lag()
), and cumulative aggregates (like cummean()
).如果要處理的數據包含許多的表格怎麼辦?
left_join(), right_join(), inner_join()
ggplot2
作圖是 EDA 的一把瑞士刀。在應用技術之前,可以先想想
先看看這個 plots to avoid
學習途徑:plot()
- qplot()
- ggplot()
>> interactive plot rCharts, plotly, networkD3, dygraphs… (視你的應用需求而定)。 有些套件本身就足夠滿足妳的需求。
#install.packages('gtrendsR')
library(gtrendsR)
trends <- gtrends(c("Nerds", "Smarties"), geo ="CA")
plot(trends)
#install.packages('plotly')
library(plotly)
p <-plot(trends)
ggplotly(p)
ggplot2
的基本文法gg
代表 grammar of graphics
(data, aesthetics) + geometry
data
: a data frameaesthetics
: used to indicate x and y variables, also used to control the color, size, shape of points, heights of bars, etc.geometry
: corresponds to the type of graphics (histogram, box plot,…)library(ggplot2)
gg <- ggplot(diamonds, aes(price, carat)) +
geom_point(color = "brown4") # scatter plot; size=1.5, shape=18
gg
gg <- gg + ggtitle("Diamond carat and price")
diamonds %>% # Start with the 'diamonds' dataset
filter(cut == "Ideal") %>% # Then, filter down to rows where cut == Ideal
ggplot(aes(x=color,y=price)) + # Then, plot using ggplot
geom_boxplot() # with and create a boxplot
再回來玩 gtrendsR
library(gtrendsR)
# https://rdrr.io/cran/gtrendsR/man/gtrends.html
#define the keywords
keywords=c("Paris","New York","Barcelona")
#set the geographic area: DE = Germany
country=c('TW')
#set the time window
time=("2010-01-01 2018-08-27")
#set channels
channel='web'
trends = gtrends(keywords, gprop =channel,geo=country, time = time )
#select only interst over time
time_trend=trends$interest_over_time
head(time_trend)
plot<-ggplot(data=time_trend, aes(x=date, y=hits,group=keyword,col=keyword))+
geom_line()+xlab('Time')+ylab('Relative Interest')+ theme_bw()+
theme(legend.title = element_blank(),legend.position="bottom",legend.text=element_text(size=12))+ggtitle("Google Search Volume")
plot
中文資料參考
http://molecular-service-science.com/2013/11/27/r-ggplot-tutorial-1/
http://molecular-service-science.com/2014/01/23/r-ggplot-tutorial-2/