在統計分析中,我們經常需要處理大批資料,其中有許多變數,當我們對符合某些條件的資料感興趣時,除了比照過去的作法針對資料中的變數進行統計,也可以考慮轉換資料。又例如我們進行實驗研究,受訪者分配到實驗組與控制組,我們可以參考 Hadley Wickham (http://www.jstatsoft.org/v59/i10/paper) 將結果紀錄為:
Subject | treatment | result |
---|---|---|
1001 | a | 20 |
1002 | a | 25 |
1003 | a | 10 |
1001 | b | 18 |
1002 | b | 31 |
1003 | b | 16 |
Table 1可以很快地分析a, b兩組實驗結果的平均值,進而比較差異。
tmp <- tibble(Subject=c(1001,1002,1003,1001,1002,1003),
treatment=c('a','a','a','b','b','b'),
result=c(20,25,10,18,31,16))
tmp %>%
group_by(treatment) %>%
summarize(outcome=mean(result))
## # A tibble: 2 x 2
## treatment outcome
## <chr> <dbl>
## 1 a 18.3
## 2 b 21.7
相反的,如果是以下的Table 2,很難分析兩組實驗之間的差異:
Subject | 1001 | 1002 | 1003 |
---|---|---|---|
treatmenta | 20 | 25 | 10 |
treatmentb | 18 | 31 | 16 |
配合上述的資料轉置,本週上課將介紹R
的dplyr
的套件中的指令,包括select
、filter
、 mutate
等函數,協助研究者統計資料。例如建立一個新的變數:
library(dplyr)
students<-read.table('studentsfull.txt', sep='', header=TRUE)
students.part<-mutate(students, sex=as.numeric(Gender)-1)
students.part
## ID Name Department Score Gender sex
## 1 10322011 Ariel Aerospace 78 F 0
## 2 10325023 Becky Physics 86 F 0
## 3 10430101 Carl Journalism 69 M 1
## 4 10401032 Dimitri English 83 M 1
## 5 10307120 Enrique Chemistry 80 M 1
## 6 10207005 Fernando Chemistry 66 M 1
## 7 10305019 George Mechanics 75 F 0
## 8 10305022 Howell Mechanics 81 M 1
## 9 10305029 Ian Mechanics 60 M 1
## 10 10305031 Julio Mechanics 89 M 1
## 11 10322014 Kaori Aerospace 82 F 0
## 12 10425026 Luke Physics 88 M 1
## 13 10401022 Miguel English 92 M 1
## 14 10501006 Neo English 77 M 1
## 15 10321010 Olivia Economics 85 F 0
## 16 10321011 Peter Economics 88 M 1
## 17 10405017 Qing Mechanics 88 F 0
## 18 10422007 Ricky Aerospace 91 M 1
## 19 10422008 Seiko Aerospace 80 F 0
## 20 10430005 Terresa Journalism 62 F 0
## 21 10530009 Usla Journalism 87 F 0
## 22 10421001 Vivian Economics 70 F 0
## 23 10307018 Wendy Chemistry 85 F 0
## 24 10425003 Xing Physics 93 M 1
## 25 10221030 Yoko Economics 66 F 0
## 26 10430015 Zoe Journalism 92 F 0
之前我們學習R
的基礎指令,而dplyr
提供許多指令幫我們整理資料。Hadley Wickman 發展了plyr
套件,然後又發展dplyr
套件。為了節省時間,我們直接討論dplyr
的幾個實用的函數。
在下載dplyr
套件之後,請嘗試這個指令:
library(dplyr)
tibble(
s=c("all","at","air","age", "angle"),
x = 1:5,
y = 1,
z = x + y,
)
## # A tibble: 5 x 4
## s x y z
## <chr> <int> <dbl> <dbl>
## 1 all 1 1 2
## 2 at 2 1 3
## 3 air 3 1 4
## 4 age 4 1 5
## 5 angle 5 1 6
或者是:
data_frame(s=c("all","at","air","age", "angle"), x = 1:5, y = 1, z = x + y)
## # A tibble: 5 x 4
## s x y z
## <chr> <int> <dbl> <dbl>
## 1 all 1 1 2
## 2 at 2 1 3
## 3 air 3 1 4
## 4 age 4 1 5
## 5 angle 5 1 6
這兩個表格顯示tibble表格的彈性,不需要像資料框(data.frame)需要那麼多向量。
tibble是一個新的資料型態,比資料框多了變數的資訊,而且會顯示前面十個觀察值的資訊,以及螢幕剛好足夠容納的下的變數。例如打開TEDS2016_indQE(CSES).sav這個檔案,但是把它視為tibble而不是data.frame:
library(foreign)
teds2016<-read.spss('TEDS2016_indQE(CSES).sav', to.data.frame=TRUE)
## re-encoding from CP950
as_tibble(teds2016)
## # A tibble: 1,690 x 80
## A1 A2 A3 A4a A4b A4c A5 A6 Q1 Q2 Q3
## <dbl> <dbl> <fct> <fct> <fct> <fct> <dbl> <fct> <fct> <fct> <fct>
## 1 1.02e12 1.61e5 Male Feb 20 2016 1.04 Mand… Not … Fair… Disa…
## 2 1.02e12 1.61e5 Male Feb 22 2016 1.16 Mand… Not … Fair… Neit…
## 3 1.02e12 1.61e5 Male Jan 31 2016 0.643 Mand… Not … Very… Agree
## 4 1.02e12 1.61e5 Male Feb 2 2016 1.20 Mand… Not … Fair… Disa…
## 5 1.02e12 1.61e5 Male Feb 3 2016 0.768 Mand… Not … Not … Don'…
## 6 1.02e12 1.61e5 Male Feb 2 2016 1.25 Mand… Not … Not … Disa…
## 7 1.02e12 1.61e5 Male Feb 19 2016 0.676 Taiw… Some… Not … Don'…
## 8 1.02e12 1.61e5 Male Feb 3 2016 0.793 Mand… Some… Fair… Agree
## 9 1.02e12 1.60e6 Male Jan 21 2016 0.768 Taiw… Not … Not … Don'…
## 10 1.02e12 1.60e6 Male Jan 21 2016 0.734 Mand… Not … Not … Disa…
## # ... with 1,680 more rows, and 69 more variables: Q4a <fct>, Q4b <fct>,
## # Q4c <fct>, Q4d <fct>, Q4e <fct>, Q4f <fct>, Q4g <fct>, Q4h <fct>,
## # Q5a <fct>, Q5b <fct>, Q5c <fct>, Q6a <fct>, Q6b <fct>, Q6c <fct>,
## # Q6d <fct>, Q6e <fct>, Q6f <fct>, Q6g <fct>, Q7 <fct>, Q8 <fct>,
## # Q9 <fct>, Q10a <fct>, Q10b <fct>, Q11 <fct>, Q12P1a <fct>,
## # Q12P1b <fct>, Q12LHa <fct>, Q12LHb <fct>, Q12LHc <fct>, Q13a <fct>,
## # Q13b <fct>, Q13c <fct>, Q14 <fct>, Q15a <fct>, Q15b <fct>, Q15c <fct>,
## # Q15d <fct>, Q15e <fct>, Q16a <fct>, Q16b <fct>, Q16c <fct>,
## # Q19a <fct>, Q19b <fct>, Q19c <fct>, Q19d <fct>, Q19e <fct>, Q20 <fct>,
## # Q21 <fct>, Q22a <fct>, Q22b <fct>, Q22c <fct>, Q22d <fct>, D1b <fct>,
## # D2 <fct>, D3 <fct>, D4 <fct>, D5 <fct>, D6 <fct>, D7 <fct>, D8 <fct>,
## # D9 <fct>, D10 <fct>, D11 <fct>, D13 <fct>, D14 <fct>, D15 <fct>,
## # D16 <fct>, D17 <fct>, D18 <fct>
這筆資料來自於台灣選舉與民主化調查(http://teds.nccu.edu.tw/main.php)。可以看出tibble比較適用於大量的資料,讓資料分析更加容易。
而tibble格式的資料子集合可以是該變數的格式,也可以是資料框,可以用參數drop加以控制。例如:
class(teds2016[,1])
## [1] "numeric"
class(teds2016[,1, drop=TRUE])
## [1] "numeric"
那麼,tibble的用處是什麼?tibble 來自於Hadley Wickham 發展的簡潔數據(tidy dataset)概念,簡潔數據的目標是讓每一個變數都有一個欄位(每一欄都是一個變數),而且每一筆觀察值都有一列,而且每一個值都有一儲存格(也就是每一個儲存格只有一個值,沒有例如\(a/b\)是由兩個值所構成)。詳見Garrett Grolemund & Hadley Wicham (http://r4ds.had.co.nz/index.html)。 tidy dataset也希望資料在同一個表,而非來自於不同的表。
雖然以下的指令適用於資料框以及整潔數據,但是整潔數據方便大數據分析。例如我們想要pp0797b2這筆資料加權之後的性別統計:
teds2016 %>%
count(D2)
## # A tibble: 2 x 2
## D2 n
## <fct> <int>
## 1 Male 868
## 2 Female 822
Hadley Wickham也是ggplot2
的作者,因此tibble資料適合於ggplot2
的視覺化,例如我們想呈現性別的分佈,不一定用得到tibble:
library(ggplot2)
ggplot(teds2016, aes(x=D2)) +
geom_bar(stat='count', fill='steelblue') +
theme(text=element_text(family="HanWangMingBold", size=14))
但是要呈現兩個變數之間的聯合機率的次數,我們需要計算兩個變數的每一個類別的交叉,然後可以更容易使用ggplot2。例如我們想知道不同性別的受訪者是否參與工會:
df.union<-teds2016 %>%
group_by(D2) %>%
count(D5)
df.union
## # A tibble: 6 x 3
## # Groups: D2 [2]
## D2 D5 n
## <fct> <fct> <int>
## 1 Male R is member of a union 200
## 2 Male R is not a member of a union 664
## 3 Male Don't know 4
## 4 Female R is member of a union 164
## 5 Female R is not a member of a union 651
## 6 Female Don't know 7
在這個例子中: - 就性別分組,然後計算有無加入工會的個案數 - 上述指令中的%>%被稱為pipeline或者是pipe operator,有點像是兩行指令之間的連結,可執行多行指令,讓語法看起來更簡潔。
接下來用tibble格式的df.union 畫直方圖:
g<-ggplot(df.union, aes(D2, n, fill=D5)) +
geom_bar(stat='identity') +
theme(text=element_text(size=14))
g
由此可以看出,tibble資料以及dplyr
的指令可以直覺式地處理資料。
我們也可以計算每一個交叉細格的條件機率:
df.union<-teds2016 %>%
group_by(D2) %>%
count(D5) %>%
mutate(N=sum(n)) %>%
mutate(pct=100*n/N)
df.union
## # A tibble: 6 x 5
## # Groups: D2 [2]
## D2 D5 n N pct
## <fct> <fct> <int> <int> <dbl>
## 1 Male R is member of a union 200 868 23.0
## 2 Male R is not a member of a union 664 868 76.5
## 3 Male Don't know 4 868 0.461
## 4 Female R is member of a union 164 822 20.0
## 5 Female R is not a member of a union 651 822 79.2
## 6 Female Don't know 7 822 0.852
然後按照上述方式畫圖,即可得到性別與參與工會的堆疊圖:
g<-ggplot(df.union, aes(D2, pct, fill=D5)) +
geom_bar(stat='identity') +
theme(text=element_text(size=14))
g
tibble的子集合跟資料框有一些不同,例如:
df <- tibble(
x = runif(5),
y = rnorm(5),
z = 4
)
df
## # A tibble: 5 x 3
## x y z
## <dbl> <dbl> <dbl>
## 1 0.624 0.621 4
## 2 0.254 -0.492 4
## 3 0.176 -0.258 4
## 4 0.704 -0.893 4
## 5 0.749 -0.209 4
子集合的方式有好幾種:
df$x
## [1] 0.6239356 0.2536799 0.1756172 0.7038229 0.7491670
df[['x']]
## [1] 0.6239356 0.2536799 0.1756172 0.7038229 0.7491670
df[,"z"]
## # A tibble: 5 x 1
## z
## <dbl>
## 1 4
## 2 4
## 3 4
## 4 4
## 5 4
重新命名變數名稱,新的變數名稱在前面:
df2 <- df %>%
rename(
v1=x, v2=y, 'group'=z
)
df2
## # A tibble: 5 x 3
## v1 v2 group
## <dbl> <dbl> <dbl>
## 1 0.624 0.621 4
## 2 0.254 -0.492 4
## 3 0.176 -0.258 4
## 4 0.704 -0.893 4
## 5 0.749 -0.209 4
以下我們運用tibble來處理資料。
dplyr
指令可以產生新的變數,也可以產生統計的結果。首先介紹轉換資料但是不產生統計摘要(例如平均值、最小值、最大值等等)結果的指令。
在一個二維的資料型態,假設我們想留下部分欄位的資料,捨棄其他欄位,可以用select
這個函數。例如:
library(dplyr)
dt <- tibble(
s=c("B", "B", "A","B","A","C", "B", "B","B", "B", "A","B","A","C", "B", "B"),
x = 1:16,
y = 1,
z = x + 2*y,
)
dt %>% select(z, s)
## # A tibble: 16 x 2
## z s
## <dbl> <chr>
## 1 3 B
## 2 4 B
## 3 5 A
## 4 6 B
## 5 7 A
## 6 8 C
## 7 9 B
## 8 10 B
## 9 11 B
## 10 12 B
## 11 13 A
## 12 14 B
## 13 15 A
## 14 16 C
## 15 17 B
## 16 18 B
filter
可以篩選符合條件的變數的觀察值,篩選的變數可以超過一個,例如:
Orange %>% filter (age >1000, circumference > 100)
## Tree age circumference
## 1 1 1004 115
## 2 1 1231 120
## 3 1 1372 142
## 4 1 1582 145
## 5 2 1004 156
## 6 2 1231 172
## 7 2 1372 203
## 8 2 1582 203
## 9 3 1004 108
## 10 3 1231 115
## 11 3 1372 139
## 12 3 1582 140
## 13 4 1004 167
## 14 4 1231 179
## 15 4 1372 209
## 16 4 1582 214
## 17 5 1004 125
## 18 5 1231 142
## 19 5 1372 174
## 20 5 1582 177
類別變數或者是數字變數都可以篩選觀察值。
我們可以直接在資料中創造一個新變數,不需要再用錢字符號($),並且轉換資料型態,例如:
dt_mutate <- mutate(dt, S=as.factor(s), X=x*100)
dt_mutate <- mutate(dt_mutate, sn=as.numeric(S))
dt_mutate
## # A tibble: 16 x 7
## s x y z S X sn
## <chr> <int> <dbl> <dbl> <fct> <dbl> <dbl>
## 1 B 1 1 3 B 100 2
## 2 B 2 1 4 B 200 2
## 3 A 3 1 5 A 300 1
## 4 B 4 1 6 B 400 2
## 5 A 5 1 7 A 500 1
## 6 C 6 1 8 C 600 3
## 7 B 7 1 9 B 700 2
## 8 B 8 1 10 B 800 2
## 9 B 9 1 11 B 900 2
## 10 B 10 1 12 B 1000 2
## 11 A 11 1 13 A 1100 1
## 12 B 12 1 14 B 1200 2
## 13 A 13 1 15 A 1300 1
## 14 C 14 1 16 C 1400 3
## 15 B 15 1 17 B 1500 2
## 16 B 16 1 18 B 1600 2
我們可以根據某一個或者一個以上的變數遞增或是遞減排序資料,例如:
dt_arrange = arrange(dt, s, desc(z))
dt_arrange
## # A tibble: 16 x 4
## s x y z
## <chr> <int> <dbl> <dbl>
## 1 A 13 1 15
## 2 A 11 1 13
## 3 A 5 1 7
## 4 A 3 1 5
## 5 B 16 1 18
## 6 B 15 1 17
## 7 B 12 1 14
## 8 B 10 1 12
## 9 B 9 1 11
## 10 B 8 1 10
## 11 B 7 1 9
## 12 B 4 1 6
## 13 B 2 1 4
## 14 B 1 1 3
## 15 C 14 1 16
## 16 C 6 1 8
排序的時候需要注意該變數是否已經設定順序。例如Orange資料中的Tree已經排序過,得到的排序結果不會如我們預期:
class(Orange$Tree)
## [1] "ordered" "factor"
Orange %>% arrange (Tree, age)
## Tree age circumference
## 1 3 118 30
## 2 3 484 51
## 3 3 664 75
## 4 3 1004 108
## 5 3 1231 115
## 6 3 1372 139
## 7 3 1582 140
## 8 1 118 30
## 9 1 484 58
## 10 1 664 87
## 11 1 1004 115
## 12 1 1231 120
## 13 1 1372 142
## 14 1 1582 145
## 15 5 118 30
## 16 5 484 49
## 17 5 664 81
## 18 5 1004 125
## 19 5 1231 142
## 20 5 1372 174
## 21 5 1582 177
## 22 2 118 33
## 23 2 484 69
## 24 2 664 111
## 25 2 1004 156
## 26 2 1231 172
## 27 2 1372 203
## 28 2 1582 203
## 29 4 118 32
## 30 4 484 62
## 31 4 664 112
## 32 4 1004 167
## 33 4 1231 179
## 34 4 1372 209
## 35 4 1582 214
Orange %>% mutate(tree=factor(Tree, levels=c('1','2','3','4','5'))) %>%
arrange (desc(tree), age)
## Tree age circumference tree
## 1 5 118 30 5
## 2 5 484 49 5
## 3 5 664 81 5
## 4 5 1004 125 5
## 5 5 1231 142 5
## 6 5 1372 174 5
## 7 5 1582 177 5
## 8 4 118 32 4
## 9 4 484 62 4
## 10 4 664 112 4
## 11 4 1004 167 4
## 12 4 1231 179 4
## 13 4 1372 209 4
## 14 4 1582 214 4
## 15 3 118 30 3
## 16 3 484 51 3
## 17 3 664 75 3
## 18 3 1004 108 3
## 19 3 1231 115 3
## 20 3 1372 139 3
## 21 3 1582 140 3
## 22 2 118 33 2
## 23 2 484 69 2
## 24 2 664 111 2
## 25 2 1004 156 2
## 26 2 1231 172 2
## 27 2 1372 203 2
## 28 2 1582 203 2
## 29 1 118 30 1
## 30 1 484 58 1
## 31 1 664 87 1
## 32 1 1004 115 1
## 33 1 1231 120 1
## 34 1 1372 142 1
## 35 1 1582 145 1
我們可以直接輸出某一個變數的統計結果:
summarize(dt, mean(x))
## # A tibble: 1 x 1
## `mean(x)`
## <dbl>
## 1 8.5
或者是轉成另一個變數,方便後續的分析,但是dplyr
會存成一個tibble資料,所以需要再取出:
dt.sze=summarize(dt, x.avg=mean(x), z.avg=mean(z))
dt.sze[,1]
## # A tibble: 1 x 1
## x.avg
## <dbl>
## 1 8.5
dt.sze[,2]
## # A tibble: 1 x 1
## z.avg
## <dbl>
## 1 10.5
summarize
可以計算的統計有:
(請見DSC2014tutorial)
例如我們想要知道mtcars
這筆資料中cyl的個數、平均數跟類別的數目:
mtcars_n<-summarize(mtcars, n(), mean(cyl), n_distinct(cyl))
我們可以根據資料內的類別變數對另一個變數進行統計,例如計算平均值,使用group_by()
這個函數:
summarize(group_by(dt, s), mean(z))
## # A tibble: 3 x 2
## s `mean(z)`
## <chr> <dbl>
## 1 A 10
## 2 B 10.4
## 3 C 12
又例如我們想分析不同科系的學生成績:
st <- read.table('studentsfull.txt', header=T)
score.report <- st %>%
group_by(Department) %>%
summarize(Avg=mean(Score)) %>%
arrange (Department)
score.report
## # A tibble: 7 x 2
## Department Avg
## <fct> <dbl>
## 1 Aerospace 82.8
## 2 Chemistry 77
## 3 Economics 77.2
## 4 English 84
## 5 Journalism 77.5
## 6 Mechanics 78.6
## 7 Physics 89
在上面例子中:
如果資料內有遺漏值,可以設定na.rm
這個參數為真,去除遺漏值,再進行統計,例如以flights這筆資料為例,根據tailnum也就是班機號碼,彙總計算班機次數以及距離:
library(nycflights13)
by_tailnum <- group_by(flights, tailnum)
delay <- summarise(by_tailnum,
count = n(),
dist = mean(distance, na.rm = TRUE))
delay
## # A tibble: 4,044 x 3
## tailnum count dist
## <chr> <int> <dbl>
## 1 D942DN 4 854.
## 2 N0EGMQ 371 676.
## 3 N10156 153 758.
## 4 N102UW 48 536.
## 5 N103US 46 535.
## 6 N104UW 47 535.
## 7 N10575 289 520.
## 8 N105UW 45 525.
## 9 N107US 41 529.
## 10 N108UW 60 534.
## # ... with 4,034 more rows
或者是(參考:https://dplyr.tidyverse.org/articles/dplyr.html ):
flights %>% group_by(tailnum) %>%
summarize(count=n(), avgdist=mean(distance, na.rm=TRUE))
## # A tibble: 4,044 x 3
## tailnum count avgdist
## <chr> <int> <dbl>
## 1 D942DN 4 854.
## 2 N0EGMQ 371 676.
## 3 N10156 153 758.
## 4 N102UW 48 536.
## 5 N103US 46 535.
## 6 N104UW 47 535.
## 7 N10575 289 520.
## 8 N105UW 45 525.
## 9 N107US 41 529.
## 10 N108UW 60 534.
## # ... with 4,034 more rows
以上的說明希望大家活用dplyr
,進行統計,並且結合資料視覺化。
dplyr
提供了許多轉換資料以及彙總計算的功能,而針對資料的轉換,reshape2
套件有很大的幫助。reshape2
也是由 Hadley Wickham所寫,該套件裡最重要的兩個函數便是 melt() 與 dcast(),如同字面上的意思,melt 是熔化的意思,也就是將資料由多變數熔成較少變數且較長的資料,可以想像資料變長;cast 是鑄造的意思,也就是將資料由較少變數鑄造成較多變數且較寬的資料,可以想像資料變短。cast 有分 dcast 與 acast,只差在要輸出的形式是 data.frame 或是 array。(以上文字參考:https://blog.stranity.com.tw/2016/12/12/r語言reshape2套件/ )
將資料由少變數變形為較寬的資料,在過程中可以加上函數。例如有一筆資料表示銀行的房貸金額,我們先讀取資料,過程中擷取年份與月份:
library(DSC2014Tutorial)
ETL_file("cl_info_other.csv")
## [1] "/Library/Frameworks/R.framework/Versions/3.5/Resources/library/DSC2014Tutorial/ETL/cl_info_other_unix.csv"
bank.info = read.table(file=ETL_file("cl_info_other.csv"),sep=",",stringsAsFactors=F,header=T)
bank.part=mutate(bank.info,
bank_code = as.factor(bank_code),
etl_dt = substr(etl_dt, 1, 7))
bank.part=mutate(bank.part, yearmonth=format(etl_dt, format='%Y-%m'))
bank.part<-select(bank.part, bank_nm, yearmonth, mortgage_bal)
head(bank.part)
## bank_nm yearmonth mortgage_bal
## 1 日商瑞穗實業銀行 2013-11 0.0000e+00
## 2 台北縣淡水第一信用合作社 2013-11 1.6873e+10
## 3 萬泰商業銀行 2013-11 5.6240e+09
## 4 台中市第二信用合作社 2013-11 1.8949e+10
## 5 基隆市第二信用合作社 2013-11 3.7730e+09
## 6 高雄第三信用合作社 2013-11 2.4760e+09
DSC2014Tutorial
套件的說明,請先安裝該套件,並且輸入slides(‘ETL1’)。如果有問題請參考授課大綱。)
然後就銀行名稱(bank_nm)以及年度月份(yearmonth)轉形為寬表,可顯示銀行名稱、每一個時間點的銀行貸款總額(為了顯示方便,銀行貸款一律除以10億):
library(reshape2)
bank.part$mortgage_bal.new=bank.part$mortgage_bal/10e+9
wtable<-dcast(bank.part, bank_nm ~ yearmonth, value.var=c('mortgage_bal.new'), sum)
wtable
## bank_nm 2013-11 2013-12 2014-01 2014-04 2014-05
## 1 安泰商業銀行 455.8923 20.3757 15.2651 10.1400 5.0763
## 2 澳商澳盛銀行 39.6716 0.0000 4.7207 0.0000 0.0000
## 3 澳商澳洲紐西蘭銀行 0.0154 0.0000 0.0000 0.0000 0.0000
## 4 澳盛 8.6770 12.9826 3.4501 7.1376 3.5712
## 5 板信商業銀行 330.0505 10.2763 8.2238 5.1035 2.5702
## 6 寶華商業銀行 52.4839 0.0000 0.0000 0.0000 0.0000
## 7 比利時商比利時聯合銀行 0.1566 0.0000 0.0000 0.0000 0.0000
## 8 比利時商富通銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 9 大陸商交通銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 10 大陸商中國建設銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 11 大陸商中國銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 12 大台北商業銀行 52.8824 3.0092 2.5724 0.0000 0.0000
## 13 大眾商業銀行 671.4575 37.2538 28.5782 18.7963 9.4068
## 14 淡水第一信用合作社 64.7933 9.7628 7.1920 5.1138 2.5813
## 15 稻江商業銀行 14.9729 0.0000 0.0000 0.0000 0.0000
## 16 德商德意志銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 17 第七商業銀行 12.9705 0.0000 0.0000 0.0000 0.0000
## 18 第一商業銀行 2164.1011 116.9979 86.9194 58.4418 29.2921
## 19 法國東方匯理銀行 0.0858 0.0000 0.0000 0.0000 0.0000
## 20 法國興業銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 21 法商法國巴黎銀行 0.6860 0.0024 0.0018 0.0012 0.0006
## 22 法商佳信銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 23 菲律賓首都銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 24 斐商標準銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 25 高雄第二信用合作社 17.3308 0.0000 0.0000 0.0000 0.0000
## 26 高雄第三信用合作社 55.6903 0.0000 0.0000 0.0000 0.0000
## 27 高雄市第三信用合作社 24.8881 2.8013 2.1591 1.6027 0.7962
## 28 高雄銀行 292.3132 12.5998 9.2073 6.6557 3.3527
## 29 國泰世華商業銀行 2223.2194 102.0286 78.8050 51.0160 25.5519
## 30 合作金庫商業銀行 3767.5942 169.3300 134.3408 88.9293 44.6074
## 31 合作金庫銀行 111.2887 0.0000 0.0000 0.0000 0.0000
## 32 荷蘭商安智銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 33 荷商安銀銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 34 花蓮第二信用合作社 121.8997 4.8504 3.5344 2.4755 1.2451
## 35 花蓮第一信用合作社 61.0537 3.8185 2.7883 1.8716 0.9289
## 36 花旗 390.1259 32.9079 24.3761 17.1927 8.5963
## 37 華南商業銀行 2576.4859 158.3480 118.3445 79.1740 39.6014
## 38 華泰商業銀行 120.0937 5.5938 3.9813 2.5195 1.2510
## 39 基隆第一信用合作社 23.5140 3.6329 2.6218 1.9136 0.9598
## 40 基隆市第二信用合作社 44.7062 3.0869 2.3235 1.7251 0.8534
## 41 基隆市第一信用合作社 42.0648 0.0000 0.0000 0.0000 0.0000
## 42 加拿大商豐業銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 43 嘉義巿第四信用合作社 1.0601 0.0000 0.0000 0.0000 0.0000
## 44 嘉義市第三信用合作社 15.8956 1.4514 1.0487 0.7396 0.3728
## 45 建華商業銀行 172.4026 0.0000 0.0000 0.0000 0.0000
## 46 交通銀行 35.9057 0.0000 0.0000 0.0000 0.0000
## 47 金門縣信用合作社 3.1091 0.3467 0.2311 0.1838 0.0928
## 48 京城商業銀行 184.8479 6.1705 4.4346 3.3029 1.6557
## 49 聯邦商業銀行 562.6416 23.2065 17.1469 11.7545 5.8939
## 50 美國運通銀行 0.0005 0.0000 0.0000 0.0000 0.0000
## 51 美商道富銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 52 美商富國銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 53 美商花旗銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 54 美商加州聯合銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 55 美商美國紐約梅隆銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 56 美商美國紐約銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 57 美商美國銀行 0.0314 0.0000 0.0000 0.0000 0.0000
## 58 美商美聯銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 59 美商摩根大通銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 60 苗栗縣竹南信用合作社 21.3096 0.0000 0.0000 0.0000 0.0000
## 61 澎湖第二信用合作社 5.1287 0.8407 0.6071 0.4191 0.2132
## 62 澎湖縣第二信用合作社 5.7510 0.0000 0.0000 0.0000 0.0000
## 63 澎湖縣第一信用合作社 2.8879 0.1763 0.1185 0.0907 0.0455
## 64 日商瑞穗實業銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 65 日商瑞穗銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 66 日商三井住友銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 67 日商三菱東京日聯銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 68 日盛國際商業銀行 414.1284 16.4723 12.2290 8.4252 4.2223
## 69 瑞士商瑞士信貸銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 70 瑞士商瑞士銀行 0.6944 0.0424 0.0330 0.0212 0.0106
## 71 瑞興商業銀行 0.0000 1.0222 1.0179 2.0400 1.0211
## 72 三信商業銀行 156.5468 7.4360 5.5540 3.7230 1.8631
## 73 上海商業儲蓄銀行 854.4311 45.8736 34.0033 23.7441 11.8944
## 74 台北富邦銀行 2162.6112 112.9597 84.0778 57.5957 28.7917
## 75 台北市第九信用合作社 26.2689 2.5787 1.8887 1.2268 0.6156
## 76 台北市第五信用合作社 26.4813 1.6851 1.2204 0.8773 0.4431
## 77 台北市第一信用合作社 15.9363 0.0000 0.0000 0.0000 0.0000
## 78 台北縣淡水第一信用合作社 111.7306 0.0000 0.0000 0.0000 0.0000
## 79 台北縣淡水信用合作社 20.4316 0.4531 0.4405 0.0000 0.0000
## 80 台南第六信用合作社 0.0000 0.0000 0.0000 0.0000 0.0000
## 81 台南第三信用合作社 37.0272 2.8486 2.0862 1.4591 0.7347
## 82 台新國際商業銀行 1797.0183 86.2433 65.5713 43.9081 22.0041
## 83 台中商業銀行 225.6101 20.8217 14.8320 11.0376 5.5510
## 84 台中市第二信用合作社 137.3252 5.1242 3.7208 2.6652 1.3267
## 85 臺南區中小企業銀行 10.6257 0.0000 0.0000 0.0000 0.0000
## 86 臺灣工業銀行 0.0239 0.0000 0.0000 0.0000 0.0000
## 87 臺灣土地銀行 4726.7059 246.4167 184.5319 127.5156 64.0046
## 88 臺灣新光商業銀行 593.9176 40.1682 29.7785 21.0930 10.5613
## 89 臺灣銀行 2738.6589 171.2308 123.4089 89.4212 44.7856
## 90 臺灣中小企業銀行 1245.4765 55.6679 41.1375 27.9560 14.0726
## 91 臺中商業銀行 168.1371 0.0000 0.0000 0.0000 0.0000
## 92 泰國盤谷銀行 0.0048 0.0000 0.0000 0.0000 0.0000
## 93 桃園信用合作社 21.6680 1.0406 0.6054 0.5628 0.2889
## 94 萬泰商業銀行 78.5559 9.5962 6.7137 4.8711 2.4440
## 95 西班牙商西班牙對外銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 96 香港東亞銀行 0.0096 0.0000 0.0000 0.0000 0.0000
## 97 香港上海匯豐銀行 338.4479 0.0000 0.0000 0.0000 0.0000
## 98 新北市淡水信用合作社 0.0000 0.4412 0.2242 0.4570 0.2283
## 99 新加坡大華銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 100 新加坡商新加坡華僑銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 101 新加坡商星展銀行 76.7716 0.0000 0.0000 0.0000 0.0000
## 102 新竹第三信用合作社 17.5981 2.8885 2.0264 1.4001 0.7017
## 103 新竹第一信用合作社 28.7734 4.8625 3.6611 2.5519 1.3054
## 104 新竹國際商業銀行 163.9289 0.0000 0.0000 0.0000 0.0000
## 105 新竹市第三信用合作社 30.3709 0.0000 0.0000 0.0000 0.0000
## 106 新竹市第一信用合作社 47.3216 0.0000 0.0000 0.0000 0.0000
## 107 星展 54.7337 16.3461 11.4036 8.4414 4.2310
## 108 陽信商業銀行 434.9034 16.7865 12.8226 7.9943 4.0000
## 109 宜蘭信用合社 10.0521 0.0000 0.1415 0.0000 0.0000
## 110 宜蘭信用合作社 0.9360 0.8064 0.3497 0.4507 0.2309
## 111 英商巴克萊銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 112 英商渣打銀行 16.4841 0.0000 0.0000 0.0000 0.0000
## 113 永豐商業銀行 2068.4916 90.6752 67.6777 44.2109 22.0346
## 114 玉山商業銀行 1514.4453 83.4300 61.3086 40.9703 20.4765
## 115 元大商業銀行 449.6893 35.2202 24.8519 18.1559 9.1095
## 116 遠東國際商業銀行 820.8375 44.3036 32.6891 21.8612 10.9321
## 117 渣打國際商業銀行 990.2054 64.2683 47.9260 32.0244 16.1259
## 118 彰化第六信用合作社 49.2319 2.9499 2.1565 1.5759 0.7850
## 119 彰化第十信用合作社 12.1791 1.1159 0.7626 0.5754 0.2882
## 120 彰化第五信用合作社 8.0686 0.6685 0.4041 0.3725 0.1880
## 121 彰化第一信用合作社 13.5215 1.2920 0.9367 0.6600 0.3250
## 122 彰化商業銀行 1526.2329 94.9249 72.1288 48.6897 24.3888
## 123 彰化縣鹿港信用合作社 26.2948 2.4027 1.7475 1.2220 0.6130
## 124 兆豐國際商業銀行 1368.9686 74.8504 52.3233 41.5007 20.8362
## 125 中國國際商業銀行 57.8369 0.0000 0.0000 0.0000 0.0000
## 126 中國輸出入銀行 0.0000 0.0000 0.0000 0.0000 0.0000
## 127 中國信託商業銀行 2483.0095 126.2968 90.6653 65.1645 32.7264
## 128 中華開發工業銀行 0.0338 0.0000 0.0000 0.0000 0.0000
## 129 竹南信用合作社 2.4617 0.0000 0.0000 0.0000 0.0000
sum可以替代為length()以及mean()。雖然寬表提供一些統計功能,也方便我們閱讀,但是無法視覺化寬表的資料。所以我們用melt轉形資料。
長表無法彙總資料,但是可以轉置資料,讓每一筆資料對應一個觀察值,而不是對應超過一個觀察值。我們先用上述的寬表,轉置為長表:
colnames(wtable)<-c("bank_nm","time1","time2","time3","time4","time5")
bank.melt=melt(wtable, id.vars=c('bank_nm'))
接下來用ggplot2
進行視覺化,目標是顯示每一個銀行在五個時間點的貸款總額變化:
library(ggplot2)
#complete
p=ggplot(bank.melt, aes(x=variable, y=value, group=bank_nm, color=bank_nm)) +
geom_line(stat="identity") +
theme(axis.text.x=element_text(family="msjh", size=10)) +
scale_x_discrete(labels = c("2013-11", "2013-12", "2014-01", "2014-04", "2014-05")) +
theme_bw()
因為原始資料之中有100多家銀行在五個時間點的資料,為了容易觀察起見,我們只繪圖三家銀行,首先隨機抽出三家銀行:
#-------------------------------------------------
#partial: 3 banks
set.seed(02139)
bankname<-unique(bank.melt$bank_nm)
r<-sample(c(1:length(bankname)), size=3, replace=F)
bankname.r <- bankname[r]
bankname.r
## [1] "大台北商業銀行" "大陸商交通銀行" "新竹第三信用合作社"
接下來畫圖:
bank.r<-bank.melt[which(bank.melt$bank_nm==bankname.r[1]|
bank.melt$bank_nm==bankname.r[2]|
bank.melt$bank_nm==bankname.r[3]),]
p=ggplot(bank.r, aes(x=variable, y=value, group=bank_nm, color=bank_nm)) +
geom_line(stat="identity") +
theme(legend.text=element_text(family="微軟正黑體", size=10)) +
scale_x_discrete(labels = c("2013-11", "2013-12", "2014-01", "2014-04", "2014-05")) +
theme_bw()
p
接下來我們看另一個範例。還記得介紹迴圈時所示範的清理主計處數據:
library(foreign)
stat.dat<-read.csv("CS3171D1A.csv",header=TRUE,sep=";",dec=".",fileEncoding="BIG5")
我們將要多擷取兩個年度的老年人口比率資料,以及擷取三個年度的失業率資料,對每一項資料我們需要一個迴圈,每一個迴圈裡面有兩個變數,也就是從哪一列跟哪一行開始讀取資料:
tempold<-data.frame()
for (i in 1:3){
for (u in 1:23){
tempold[u,i]<-stat.dat[i+1, u+1]
}
print(i)
}
## [1] 1
## [1] 2
## [1] 3
tempunemploy<-data.frame()
for (i in 1:3){
for (u in 1:23){
tempunemploy[u,i]<-stat.dat[i+13, u+1]
}
print(i)
}
## [1] 1
## [1] 2
## [1] 3
結合成為資料框,但是用tibble格式觀察資料:
countyname<-colnames(stat.dat)[-1]
temp.df <- data.frame(countyname, tempold, tempunemploy)
temp.df.t <-as_tibble(temp.df); temp.df.t
## # A tibble: 23 x 7
## countyname V1 V2 V3 V1.1 V2.1 V3.1
## * <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 臺北縣 6.37 6.44 6.55 3 4.9 5.5
## 2 宜蘭縣 10.2 10.5 10.8 3.6 5 5.4
## 3 桃園縣 7.46 7.49 7.51 2 4.3 5.1
## 4 新竹縣 9.69 9.91 10.2 1.7 3.8 4.4
## 5 苗栗縣 11.0 11.2 11.6 2.7 4.5 4.9
## 6 臺中縣 7.16 7.32 7.5 3.5 5 5.4
## 7 彰化縣 9.42 9.73 10.0 1.7 4 5.2
## 8 南投縣 10.6 10.9 11.2 3.8 4.9 5.3
## 9 雲林縣 11.6 12.0 12.4 2.6 4.1 4.7
## 10 嘉義縣 12.4 12.8 13.1 2.8 4 5.2
## # ... with 13 more rows
在這個資料框中,V1代表2000年的老年人口,所以它有
這兩個性質,而V1.1代表2000年的失業率,也是有兩個性質,為了區隔這兩個特性,我們再結合一次,這次把失業率放在老年人口比率底下:
info <- rep('old', 23)
temp.df1<-cbind(countyname, info, tempold)
info <- rep('unemploy', 23)
temp.df2<-cbind(countyname, info, tempunemploy)
temp.df<-data.frame(rbind(temp.df1, temp.df2))
接下來用melt
指令轉置資料,並且把其中的年度資料轉換為字串資料,以方便後面的分析:
new.df<-melt(temp.df, id=c('countyname', 'info'),
variable.name=c("Time"),
measure.vars = c("V1","V2","V3"))
new.df$Year<-c()
new.df$Year[new.df$Time=='V1']<-2000
new.df$Year[new.df$Time=='V2']<-2001
new.df$Year[new.df$Time=='V3']<-2002
new.df$Year<-as.character(new.df$Year)
如果以縣市為單位,而歸納這三年的兩個變數分別的總和,可以用以下的程式畫圖:
g1<-ggplot(new.df, aes(x=countyname, y=value, fill=info)) +
geom_bar(stat='identity') +
theme(axis.text.x=element_text(family="HanWangMingBold", size=10))
g1
如果以縣市為單位,而歸納這兩個變數的每一年總和,可以用以下的程式畫圖:
g2<-ggplot(new.df, aes(x=countyname, y=value, fill=Year)) +
geom_bar(stat='identity') +
theme(axis.text.x=element_text(family="YouYuan", size=10))
g2
以上兩種統計方式都是以縣市為單位,而選擇年度(三個類別)或者是統計資料(兩個類別)做為歸納單位,但是有沒有可能同時統計這兩者?也就是每一個縣市、每一個年度、老年人口比率與失業率的數字?
g3<-ggplot(new.df, aes(x=countyname, y=value, fill=info)) +
geom_bar(stat='identity') +
facet_wrap( ~ Year) +
theme(axis.text.x=element_text(family="HanWangMingBold", size=6))
g3
以上程式使用facet_wrap()納入第二個類別變數,繪出三個直方圖,分別代表三個年度的兩個變數的比率。
以上說明寬表、長表的用途,希望能有助於資料轉置以及後續分析。
nycflights13
這個套件,然後分析flights
這筆資料,並且建立新變數「速度」,公式為距離(distance)除以飛行時間(air_time)乘以60。請問平均速度多少?最高速多少?可以用filter
篩選沒有遺漏值的觀察值,例如:tibble1<-tibble(A=c(NA, NA, NA, 100, 200, 600, NA, 100, 0, 200),
B=200,
C=c(rep(300, 5), rep(400, 5)))
tibble1 = filter(tibble1, !is.na(A))
summarize(tibble1, sum(A,B,C), mean(C))
## # A tibble: 1 x 2
## `sum(A, B, C)` `mean(C)`
## <dbl> <dbl>
## 1 4600 367.
請讀取studentsfull.txt這個檔案,然後計算不同科系同學的平均分數,再根據平均分數排序資料表:
請統計mtcars
這筆資料中cyl的各類的平均馬力(hp) 以及每加侖可以行駛的英里數(mpg):
請統計flights資料中每年的最後一天的平均出發以及抵達的遲到分鐘
請從bank.info資料挑出other_cl_bal大於100億的銀行資料,並且列出銀行的名稱。