在繼續之前,let’s have some fun! 在這程式筆記中,我們將使用漫畫人物的資料集來回顧、介紹和練習 R 的內建函數。 ( 資料來源: Kaggle.com )
🌻 read.csv()
- 讀取CSV(逗號分隔值)的文件
= read.csv("data/comics1.csv") D
🌻 nrow()
- 確認row的數量
nrow(D)
[1] 7250
🌻 ncol()
- 確認column的數量
ncol(D)
[1] 9
資料框之中 …
row
又稱為一筆資料或一筆紀錄(record),它代表一個研究對象、一個分析單位column
又稱為一個欄位、變數(variables)或屬性(attributes),它代表研究對象的某個屬性或量測值🌻 str()
-
用來檢查資料框的結構,每個column的資料種類
str(D)
'data.frame': 7250 obs. of 9 variables:
$ publisher : chr "dc" "dc" "dc" "dc" ...
$ name : chr "Batman (Bruce Wayne)" "Superman (Clark Kent)" "Green Lantern (Hal Jordan)" "James Gordon (New Earth)" ...
$ align : chr "Good" "Good" "Good" "Good" ...
$ eye : chr "Blue" "Blue" "Brown" "Brown" ...
$ hair : chr "Black" "Black" "Brown" "White" ...
$ sex : chr "Male" "Male" "Male" "Male" ...
$ alive : chr "Living" "Living" "Living" "Living" ...
$ appearances: int 3093 2496 1565 1316 1237 1231 1121 1095 1075 1028 ...
$ year : int 1939 1986 1959 1987 1940 1941 1941 1989 1969 1956 ...
🌻 summary()
是檢查資料框(每個column的)內容最方便的方式
summary(D)
publisher name align eye
Length:7250 Length:7250 Length:7250 Length:7250
Class :character Class :character Class :character Class :character
Mode :character Mode :character Mode :character Mode :character
hair sex alive appearances
Length:7250 Length:7250 Length:7250 Min. : 1
Class :character Class :character Class :character 1st Qu.: 3
Mode :character Mode :character Mode :character Median : 8
Mean : 42
3rd Qu.: 26
Max. :4043
year
Min. :1936
1st Qu.:1978
Median :1992
Mean :1989
3rd Qu.:2004
Max. :2013
🗿 QUIZ 2:
■
這個資料框的名字是什麼?
■ 我們要分析的目標對象是什麼?
■
我們感興趣的屬性是哪些?
■ 資料集有哪些是數值型的column ?
■
資料集有哪些是字串型的column ?
■
哪些是字串型的column是類別 欄位呢?
🌷
請注意,對不同資料種類的欄位,summary()
會以不同的方式進行匯總
💡 分佈 & 統計量
■
分佈 : 是一種描述變數的方式,它描述著 …
◇
變數值的變化
◇ 也就是說,變數的值是如何分佈的?
■
統計量 : 數值變數的某種具體特徵
◇ 舉例來說:
平均(mean), 中位數(median), 最小值(min), 最大值(max)
■
變數的分佈可以用兩種型式表示 :
◇ 在數字上, 用統計量表示 或者
◇ 以圖形上,用繪圖的方式表示
🌻 mean()
, median
, max
,
min()
- 取得數值變數的個別統計量
c( mean=mean(D$year), median=median(D$year),
max=max(D$year), min=min(D$year) )
mean median max min
1989 1992 2013 1936
🌻 summary
一次獲得所有主要的統計量
summary(D$year)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1936 1978 1992 1989 2004 2013
🌻 hist()
- 畫出數值變數的分佈
par(mfrow=c(1,2), mar=c(2,2,3,2), cex=0.6) # 2 plots in a row, smaller font
hist(D$year, main="year")
🌻 log()
當分佈很不均勻時,對數函數(log
)有助於減輕極端值的視覺效果
hist(D$appearances)
log(D$appearances,10) %>% hist()
🌻 table()
列出並各類別的個數
table(D$align)
Bad Good Neutral
2915 3178 1157
請注意,它是依類別名稱的字母順序排列
🌻 barplot()
視覺化離散變數的分佈
par(mfrow=c(1,1), cex=0.6) # 1 plots in a row
table(D$align) %>% barplot()
🗿 QUIZ 2.2
■
分佈是什麼意思?
■ 我們如何檢查
數值 變數的分佈?
■ 我們如何檢查
類別 變數的分佈?
■
我們可以以統計量或圖形檢查變數,哪種方式比較好呢?
■ …
■ 以統計量檢查變數 appearances
■
以圖形方式檢查變數 year
■ 以統計量檢查變數
sex
■ 以圖形方式檢查變數 eye
在R裡面,原始資料之中的字串欄位可以被儲存為因素(factor
)或字串(character
)變數,
這兩種變數之間可以相互轉換。
好比說,align
這個欄位一開始是被當作字串變數讀入,
我們可以用以下的指令將其轉變為一個具有3個不同的類別(f.align
🌻 factor()
- 將字串向量轉為因素向量
$f.align = factor(D$align, levels=c("Good","Neutral","Bad")) D
有需要的話,我們可以指定因素變數之中各類別(levels
)的排列順序
par(mfrow=c(1,2), cex=0.7)
table(D$align) %>% barplot(main="align")
table(D$f.align) %>% barplot(main="f.align")
我們將 eye
也轉為因素變數
$eye = factor(D$eye) D
現在,它變成了 8 個類別(levels)的因素變數
str(D$eye)
Factor w/ 8 levels "Black","Blue",..: 2 2 3 3 2 2 2 2 2 2 ...
🌻 level(x)
列出因素變數x
之中的所有類別
levels(D$eye)
[1] "Black" "Blue" "Brown" "Green" "others" "Red" "White" "Yellow"
若我們在 factor()
中沒有指定
levels
時,各類別將以英文字母的順序排列
table(D$eye)
Black Blue Brown Green others Red White Yellow
619 2477 2210 664 359 423 291 207
🌻 sort()
對向量進行(升冪)排列
par(mfrow=c(1,1), cex=0.7)
table(D$eye) %>% sort(dec=T) %>% barplot
summary(D)
publisher name align eye
Length:7250 Length:7250 Length:7250 Blue :2477
Class :character Class :character Class :character Brown :2210
Mode :character Mode :character Mode :character Green : 664
Black : 619
Red : 423
others : 359
(Other): 498
hair sex alive appearances
Length:7250 Length:7250 Length:7250 Min. : 1
Class :character Class :character Class :character 1st Qu.: 3
Mode :character Mode :character Mode :character Median : 8
Mean : 42
3rd Qu.: 26
Max. :4043
year f.align
Min. :1936 Good :3178
1st Qu.:1978 Neutral:1157
Median :1992 Bad :2915
Mean :1989
3rd Qu.:2004
Max. :2013
🌷 在 summary()
中,因素 (或類別) 變數最多只會列出 6
筆資料,其他則歸類為 Other 。
💡字串 (Character) vs. 因素
(Factor)
■ 字串和因素都可以用於表示類別變數。
■
雖然儲存和呈現的方式不盡相同,但大多數的情況兩者可以交換使用。
■
某些類別 columns 可能會以字串的形式被讀入。
■ 所以,我們應該檢查每一
column 的變數型態。
■
通常,我們只需維持它們的原樣,在必要時將它們轉換型態即可。
如果我們想要列出出現次數(appearances
)最多的10個漫畫人物
…
= D$year[1:10]
y y
[1] 1939 1986 1959 1987 1940 1941 1941 1989 1969 1956
🌻 sort(x)
x
的內容進行排序並返回結果
sort(y)
[1] 1939 1940 1941 1941 1956 1959 1969 1986 1987 1989
🌻 order(x)
x
的內容建立一個排序索引,(用來排序物件中的內容)
order(y)
[1] 1 5 6 7 10 3 9 2 4 8
order(y) ] y[
[1] 1939 1940 1941 1941 1956 1959 1969 1986 1987 1989
order(y) ] == sort(y) y[
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
我們可以以降冪的方式(decreasing=T
)對D$appearances
進行sort()
並
使用head()
從向量中挑選出最前面10個值
sort(D$appearances, decreasing=T) %>% head(10)
[1] 4043 3360 3093 3061 2961 2496 2258 2255 2072 2017
這樣我們可以看到D$appearances
之中最大的10個數字,但 …
他們是誰呢?
🌻 sort(x)
對x
的內容進行排序並返回結果
🌻 order(x)
依x
的內容排序建立一個索引向量,(用來重新排序其他的物件)
order(D$appearances,decreasing=T), c("year","appearances","name")] %>% head(10) D[
year appearances name
2424 1962 4043 Spider-Man (Peter Parker)
2425 1941 3360 Captain America (Steven Rogers)
1 1939 3093 Batman (Bruce Wayne)
2426 1974 3061 Wolverine (James \\"Logan\\" Howlett)
2427 1963 2961 Iron Man (Anthony \\"Tony\\" Stark)
2 1986 2496 Superman (Clark Kent)
2428 1950 2258 Thor (Thor Odinson)
2429 1961 2255 Benjamin Grimm (Earth-616)
2430 1961 2072 Reed Richards (Earth-616)
2431 1962 2017 Hulk (Robert Bruce Banner)
如此我們可以按順序看到前10名最常出現的角色的出現年分(year
)、出現次數(appearances
)和名稱
(name
)。
🌻 subset(x, 條件, select=y)
依照所給定的條件篩選row,並依欄位名稱選擇column
= subset(D, alive=="Deceased" & sex=="Female", select=c("year","appearances","name"))
d order(d$appearances, decreasing=T), ] %>% head(10) d[
year appearances name
2450 1963 1107 Jean Grey (Earth-616)
2510 1965 384 Gwendolyne Stacy (Earth-616)
50 1999 301 Kendra Saunders (New Earth)
2569 1975 259 Moira Kinross (Earth-616)
2571 1972 257 Namorita Prentiss (Earth-616)
2597 1964 226 Karen Page (Earth-616)
85 1971 216 Big Barda (New Earth)
103 1971 177 Talia al Ghul (New Earth)
2650 1964 170 Hela (Earth-616)
2651 1976 170 Lilandra Neramani (Earth-616)
以上,我們可以看到前10名出現次數最多的已故女性角色。
🗿 QUIZ 4.2
■ 列出出現次數為前
10 名的金髮綠眼女性角色
■ 列出 5 個最早出現的紅髮、紅眼男性的
year
, publisher
, align
, 和
name
📋 為每個程式碼區塊寫下註解,將其作為自己的筆記本。
🌻 用 sum()
來計算一個邏輯向量裡面 TRUE
的個數
sum(D$align == "Good")
[1] 3178
🌻 用 mean()
來計算一個邏輯向量裡面 TRUE
的比例
mean(D$align == "Good")
[1] 0.4383
table()
和prop.table()
🌻 table()
列出一個向量裡各不同的值出現的次數
table(D$align)
Bad Good Neutral
2915 3178 1157
🌻 prop.table()
將計數轉換成比例
table(D$align) %>% prop.table
Bad Good Neutral
0.4021 0.4383 0.1596
如果我們在table()
中放入兩個變數,會發生什麼事呢?
table(D$f.align, D$sex)
Female Male
Good 1264 1914
Neutral 432 725
Bad 676 2239
查看prop.table
的線上說明(F1),它的margin
這個參數的作用是什麼?
table(D$f.align, D$sex) %>% prop.table
Female Male
Good 0.17434 0.26400
Neutral 0.05959 0.10000
Bad 0.09324 0.30883
table(D$f.align, D$sex) %>% prop.table(1)
Female Male
Good 0.3977 0.6023
Neutral 0.3734 0.6266
Bad 0.2319 0.7681
table(D$f.align, D$sex) %>% prop.table(2)
Female Male
Good 0.5329 0.3924
Neutral 0.1821 0.1486
Bad 0.2850 0.4590
我們來練習一下,
🏆 Group
Competition Round 1
要回答Kahoot的最後兩個問題,以上我們是先做兩維的`table(),然後再從一個2x3的矩陣中去找答案。實際上,我們有有更精簡的做法,可以只算出我們想要比較的兩個數字。
🌻
tapply(value, group, fun)
依據group
對value
做fun
tapply(D$align == "Neutral", D$sex, sum)
Female Male
432 725
按性別計算中立的人數
tapply(D$align == "Neutral", D$sex, mean)
Female Male
0.1821 0.1486
按性別計算中立的角色的比例
我們來練習一下,
🏆 Group
Competition Round 2
資料中常有一些時間欄位,像是年分(year
)或年代(decade
)
$decade = (D$year - 1900) %/% 10
Dtable(D$decade)
3 4 5 6 7 8 9 10 11
28 271 106 678 823 1304 1581 1803 656
我們可以依decade算出中性角色的比例
= tapply(D$align == "Neutral", D$decade, mean) %>% round(3); v v
3 4 5 6 7 8 9 10 11
0.071 0.077 0.094 0.137 0.180 0.137 0.134 0.182 0.250
如果把這些數據繪製為圖形,將更容易觀察出趨勢。
🌻 plot(x, y, type)
以不同的方式繪製x和y方向的數據
type="p"
散點圖(預設值)type="l"
線形圖type="b"
帶標記的線圖F1
)# 繪製圖形序列以查看趨勢
par(mfcol=c(2,2), mar=c(4,3,2,1), cex=0.7)
%>% barplot() # 直條圖
v plot(names(v), v) # 散點圖
plot(names(v), v, type='l') # 線形圖
plot(names(v), v, type='b',
ylim=c(0,0.25), # 帶標記的從零開始的線圖
main="各年代中性角色的比例", # 圖表與橫軸名稱
xlab="年代")
以上哪以種方式比較容易看見正確的趨勢呢?
tapply(value, group, function)
可以一次接受多個分組變數,如
= tapply(D$align=="Bad", list(D$sex, D$decade), mean) %>% round(3); v v
3 4 5 6 7 8 9 10 11
Female 0.125 0.156 0.312 0.198 0.255 0.266 0.352 0.288 0.250
Male 0.050 0.274 0.289 0.559 0.480 0.457 0.513 0.414 0.439
🌻
lines()
在現有繪圖中添加一條線。例如,我們可以比較不同性別的壞角色比例的趨勢,如下所示。
par(mfrow=c(1,1), mar=c(3,3,2,1), cex=0.7)
plot(colnames(v), v[1,], type="l", ylim=c(0,0.6), col="red", lwd=2,
main = "按性別劃分的壞角色比例") # 添加標題
lines(colnames(v), v[2,], col="blue", lwd=2) # 添加第二條線
abline(h=seq(0,0.6,0.1), v=seq(3,10,1), col='lightgray') # 添加格線
確定前三種頭髮顏色…
= table(D$hair) %>% sort %>% tail(3) %>% names; h3 h3
[1] "Blond" "Brown" "Black"
看看前三種頭髮顏色的比例如何隨時間變化。
par(mfrow=c(1,1), mar=c(3,3,2,1), cex=0.7)
= tapply(D$hair=="Black", D$decade, mean)
v plot(names(v),v,type='l',lwd=2,col="black",ylim=c(0,0.45),
main="前三種頭髮顏色的比例隨時間的變化")
abline(h=seq(0,0.5,0.1), v=seq(3,10,1), col='lightgray')
= tapply(D$hair=="Brown", D$decade, mean)
v lines(names(v),v,type='l',lwd=2,col="brown")
= tapply(D$hair=="Blond", D$decade, mean)
v lines(names(v),v,type='l',lwd=2,col="gold")
🗿 QUIZ 6.3
現在輪到你了。請製作圖表以…
■ 檢查前三種眼睛顏色的比例趨勢
■
依據漫畫公司
跟性別
去比較存活機率
的趨勢
dc.Female dc.Male marvel.Female marvel.Male
3 0.7143 0.6923 0.0000 0.8571
4 0.7273 0.5810 0.8261 0.7438
5 0.7273 0.7547 0.8000 0.7297
6 0.8485 0.7465 0.7564 0.7082
7 0.5909 0.6964 0.6923 0.7182
8 0.7782 0.6518 0.8034 0.7293
9 0.8219 0.6911 0.8037 0.7639
10 0.8382 0.7395 0.6951 0.6447
11 0.9062 0.8525 0.8100 0.7160