關卡 1

這門課程,主要是講解Robject的入門操作。

關卡 2

R的object結構是針對資料分析所設計的。所以最簡單的object,就是一連串的數字。

關卡 3

這讓R和其他的程式語言不同,因為一般的程式語言最簡單的object會是一個數字。

關卡 4

R這樣設計的理由是因為在資料分析的應用中,我們一定是處理一些資料,而不會只有一筆資料。

關卡 5

要用R建立一個內容為10.4,5.6,3.1和6.4的向量,最常用的方式就是輸入:c(10.4,5.6,3.1,6.4)請同學依照這樣的語法建立一個這樣的向量,並且把它存到變數x。

x <- c(10.4, 5.6, 3.1, 6.4)

關卡 6

請問同學,剛剛我們輸入的語法是assignment還是expression?

assignment

關卡 7

在R中,c()可以接受任意數量的的向量參數,並且會依照順序把它們串接成一個單一向量。舉例來說:c(x,1)會在剛剛我們建立的x後面再接一個1。而c(x,2,3)則會在x之後接上2和3。請同學依照這個要領,撰寫一個expression,內容是建立一個在x後面接上x的向量。

c(x, x)

關卡 8

在R中,大部份的運算都是向量式的。舉例來說,加法+在R就是向量式。請同學輸入:c(1,2,3)+c(2,4,6)並觀察結果。

c(1, 2, 3) + c(2, 4, 6)

關卡 9

有沒有注意到,結果的第一個值,就是輸入的兩個向量的第一個值的相加呢?以此類推,一直到第三個值都還是這樣。這就是「向量式」的意思。

關卡 10

但是當相加的兩個向量長度不同的時候,會發生什麼事情呢?R會自動重複比較短的向量,補到長度和比較長的向量相同,然後用一樣的概念去做計算。請同學輸入2+c(1,2,3)試試看。

2 + c(1,2,3)

關卡 11

向量式的運算讓我們在處理資料上非常容易。在R之中,除了加減乘除之外,而許多常用的數學算式都是向量式的。例如:logexpsincostan和`sqrt、。

關卡 12

不是所有的運算都是向量式的。如果給定一個向量x,max(x)會傳回x中最大的值,而min(x)會傳回x最小的值。有時候在分析的時候,我們如果想要知道數值的範圍,這兩個函數就很有用。請同學寫一個expression來建立一個兩個值的向量,而且第一個值是x的最小值,第二個是x的最大值。

c(min(x), max(x))

關卡 13

在R中,有一個函數range就能直接傳回輸入向量的範圍(最小到最大)。請同學再算一次x的範圍,但是是使用range

range(x)

關卡 14

在R中,sum(x)會傳回x所有值的加總。length(x)函數能直接傳回x的長度。請同學利用sumlength計算x的平均值。

sum(x) / length(x)

關卡 15

R也內建許多統計相關的函數。例如mean(x)就能直接計算x的平均值。透過meansumlength,我們就能計算x的樣本變異數:sum((x-mean(x))^2)/(length(x)-1)。但是R也有內建的函數來簡化我們的工作。透過var(x),我們就能簡單用短短的函數計算樣本變異數。

關卡 16

請利用var計算x的樣本變異數。

var(x)

關卡 17

請利用sd計算x的樣本標準差。

sd(x)

關卡 18

在R中,sort(x)則會產生一個和x長度一樣的向量,但是值是由小到大排列。請同學試試看:sort(x)

sort(x)

關卡 19

在數學上,輸入的x可能是整數、實數甚至是複數。R的數學計算,會自動根據x的屬性做調整。

關卡 20

舉例來說,如果我們輸入sqrt(-17),我們會得到NaN(NotANumber)。請同學試試看輸入sqrt(-17)。這裡的sqrt代表的就是數學上開根號的運算。

sqrt(-17)

關卡 21

在數學上,對負數開根號,在實數中是沒有答案的。

關卡 22

但是若我們使用sqrt(-17+0i),這時候因為輸入的是一個複數,R會自動調整行為,不再回傳一個NaN。請同學試試看。

sqrt(-17 + 0i)

關卡 23

R也有簡易的功能可以產生一些附帶有規則的序列。例如:1:10就會產生自1至10的序列。這樣的功能,在整理資料的時候很常用。例如說,如果我們需要取出第5筆到第100筆的資料,就會用到類似的語法。請同學嘗試利用:建立一個從20到40的序列。

20:40

關卡 24

在R中,:這個運算子的優先層級很高,也就是說如果R看到:2*1:10這段expression,會優先處理1:10,然後再把所有結果乘以2。我們來讓同學試試看,請輸入:2*1:10

2 * 1:10

關卡 25

另外我們也跟各位介紹一個更泛用產生向量的方式:seqseq(1,10)在R中,其實就是1:10。請試試看輸入seq(1,10)

seq(1,10)

關卡 26

這裡的seq本質上就是一個「函數」,而seq(1,10)這段expression中,我們稱呼1和10為這個函數的arguments。讓我們來看一下seq可以接受幾個參數。請同學用之前介紹的方式,打開seq的說明文件。

?seq

關卡 27

我們可以在說明文件上,閱讀DefaultS3method之下的那段說明程式碼:seq(from=1,to=1,by=((to-from)/(length.out-1)),length.out=NULL,along.with=NULL,...)這段說明文字顯示了,seq一般來說接受五個參數,而他們分別為:fromtobylength.outalong.with

關卡 28

對於個別參數的使用方法,我們可以閱讀在Arguments之下的細節說明。比如說,from,tofrom,tothestartingand(maximal)endvaluesofthesequence.Oflength1unlessjustfromissuppliedasanunnamedargument.這段文字就說明了fromto的用法。

關卡 29

有時候,說明文字不如程式碼來得清楚,所以我們可以直接翻閱到說明文件的最底下,查閱Examples段落之中官方文件提供的seq的範例。

關卡 30

如果要嘗試跑這些範例,我們可以簡單輸入:example(seq)請同學跟著輸入。

example(seq)

關卡 31

在R中,seq的參數共有:fromtobylength.outalong.with。如果我們不指定,而是依照順序填入:seq(1,10),那就代表from是1、to是10、而by等其他argument就使用預設參數。

關卡 32

我們也可以透過指定參數名稱的方式來告訴Rseq的參數是什麼。舉例來說,seq(to=10,from=1)告訴R說參數from是1而to是10。所以結果應該要和seq(1,10)相同。請同學試試看。

seq(to = 10, from = 1)

關卡 33

利用seq產生的序列也不一定要間隔是1。如果我們希望間隔是0.5,seq函數是透過by這個參數來控制間隔的,所以只要輸入seq(1,10,by=0.5)就好了。請同學試試看。

seq(1, 10, by = 0.5)

關卡 34

有時候產生序列的方式,可以是指定開頭、間隔和長度。在seq中,這對應到frombylength.out這三個參數。請同學自己寫一個expression,產生一個從1開始,間隔2,長度為10的序列。參數請透過名稱來給定。

seq(from = 1, by = 2, length.out = 10)

關卡 35

R很聰明,在指定argument的時候不用指定全名,而只要給出前面幾個可以讓R辨別argument名稱的字母就可以了。舉例來說:seq(from=1,by=2,length=10)也可以讓R知道argumentlength.out的值是10。

關卡 36

如果我們不想要序列,而是想要重複一個數字,則可以用rep請同學試試看:rep(2,times=10)

rep(2, times = 10)

關卡 37

在R中,rep也可以作用在一個序列上。如果使用者是了argumenttimes定值,那R會將整個序列重複times次,然後接起來。請同學試試看:rep(x,times=2)

rep(x, times = 2)

關卡 38

如果我們沒有指定rep的argumenttimes,而是argumenteach,那R會把向量的每一個值個別重複each遍之後,再接起來。請同學試試看:rep(x,each=2)

rep(x, each = 2)

關卡 39

在R中,seqrep的搭配使用,在整理資料的時候很常用。有興趣的同學可以在後續的實例教材中,看看如何應用這兩個函數解決一些整理資料的問題。

關卡 40

在R中,除了數值之外,邏輯值也是很常見的。類似數值,R最基礎的object之一,就是邏輯向量。而我們看到的一個值,只是一個長度是1的向量。

關卡 41

邏輯向量常常表示資料中如:「是、否」、「男、女」之類二選一的選項。除此之外,在程式碼的流程控制,也是很常用。

關卡 42

在R中,邏輯值「真」常用TRUET來代表。「假」則用FALSEF代表。第三種在邏輯向量會出現的值,就是NA(NotAvailable)。注意:這裡的TF是一個預設值是TRUEFALSE的變數,並不是保留字。所以同學是可以更改TF的內容的!

關卡 43

我們可以利用各種「條件類型的expression」來建立邏輯向量。舉例來說,我們手上有x,就可以利用x>5來建立一個長度和x相同的邏輯向量。請同學試試看。

x > 5

關卡 44

從結果可以看到,R會拿x(c(10.4,5.6,3.1,6.4))的值一個個的和5做比較。比較大的就是TRUE,而比較小的是FALSE。

關卡 45

類似可用於建立邏輯向量的「條件」有:大於>、大於等於>=、小於<、小於等於<=、相等==和不相等!=。這類邏輯向量在整理資料時,做資料篩選上是很常用的。

關卡 46

另外邏輯運算子「且」&和「或」|也是很常用的。他們可以在兩個邏輯向量中做運算。請同學試試看:x>5&x<10

x > 5 & x < 10

關卡 47

輸出結果,應該是那些x(c(10.4,5.6,3.1,6.4))的值介於5和10之間的為TRUE,否則就為FALSE。當我們在篩選資料的時候,有時候要篩選的條件很複雜,需要用多個條件來組合而成時,就會用到&|了。

關卡 48

有時候,當資料的值無法取得的時候,R就會給它一個特殊的記號:NA。所有和NA做的運算結果,通常都會是NA。就常識來看,這很合理。因為「無法取得的數字」加上1,結果還是「無法取得」

關卡 49

我們可以利用is.na來判斷一個向量裡面有沒有NA。請同學試試看is.na(x)

is.na(x)

關卡 50

在R中,is.na(x)的結果應該都是FALSE,因為x的資料裡面沒有NA。我們來玩一個有NA的向量吧!請試試看:is.na(c(1,2,NA,3))

is.na(c(1,2,NA,3))

關卡 51

在R之中,我們已經看過兩種特別的記號:NA和NaN。NA代表的是缺失值,而NaN往往來自於數學運算中沒有定義的行為。例如:sqrt(-17)0/0Inf-Inf。在R裡面,無限大就是Inf。R對這些數學的處理是很聰明的。舉例來說,同學們可以試試看R計算Inf+1的結果:

Inf + 1

關卡 52

雖然我們理解NA和NaN的不同,但是is.na會把兩者都看成TRUE。舉例來說,請同學試試看:is.na(c(NA,NaN,1))

is.na(c(NA, NaN, 1))

關卡 53

有時候,我們需要處理文字類型的object。這些object常常用於指定繪圖的標題、或是處理一些類別形變數,如:國籍、行政區等等。這樣的資料,在R之中是透過單引號'或雙引號"來建立的。這類的資料,常常被人稱為:「字串」。

關卡 54

舉例來說,如果我們直接輸入x而不用雙引號包覆它,R會把這個x當成變數名稱,而回傳x的內容。請同學試試看輸入:x

x

關卡 55

但是如果我們輸入的是"x",那R就會認為這是一個只有一個字元、內容為“x”的字串。請同學試試看:"x"

"x"

關卡 56

由於方便教材的設計,後續操作swirl的時候,請同學儘量使用"來建立字串。

關卡 57

這類文字類型的object,在R中,\符號代表字串中的跳脫符號。舉例來說,如果我們要輸入一個包含雙引號的字串,有兩種方法:一種是用單引號'來包覆雙引號,另外一種就是在雙引號之前插入\。請同學試試看用跳脫符號的方式,輸入一個字串,內容只有一個雙引號。

"\""

關卡 58

在R中,paste是在R中常常用來做字串處理的函數。我們可以丟任意個arguments給paste,結果R會把這些argument以字串的形式接成一個字串。請同學試試看:paste("a","b")

paste("a", "b")

關卡 59

請同學試試看:paste(c("X","Y"),1:10)

paste(c("X", "Y"), 1:10)

關卡 60

你可以注意到,1:10被自動轉換成字串了。這又是一個R會自動判斷形態的例子。同時,我們可以注意到c("X","Y")重複了五次,這是因為paste也是一個向量化的函數。

關卡 61

另一個你會注意到的,是paste預設會在串接字串時,在中間留下一個空格。如果這不是你喜歡的,可以使用paste0這個和paste幾乎一模一樣的函數。除了一點:paste0預設在串接字串的時候,中間是不會有空格的。同學請試試看:paste0(c("X","Y"),1:10)

paste0(c("X", "Y"), 1:10)

關卡 62

最後,我們要介紹一個整理資料上非常重要的功能:如何挑選向量中一部份的資料。

關卡 63

第一種方法,使用坐標。在R之中,如果我們要挑選x的第一個和第三個位置的值,只要使用:x[c(1,3)]。請同學試試看。

x[c(1,3)]

關卡 64

第二種方法,是利用邏輯向量。舉例來說,如果我們要挑選x之中超過5的值,就透過x[x>5]。請同學試試看。

x[x > 5]

關卡 65

第三種方法,是削去法。如果我們要挑x_除了_第二個之外的全部的值,可以使用x[-2]

x[-2]

關卡 66

最後一個方法比較特別,我們要先介紹在R中names的概念。R的向量中,每一個值是可以有名字的。舉例來說,我們可以透過:names(x)<-c("a","b","c","d")來幫x的每個值取名。請同學試試看。

names(x) <- c("a", "b", "c", "d")

關卡 67

現在我們來把x印到螢幕上看看。

x

關卡 68

我們可以看到R現在顯示每個x的值時,也會在上一行對應的位置上印出它的名字了。

關卡 69

所以如果我們想要選取名稱為c("b","d")的值,就只要輸入:x[c("b","d")]。請同學試試看。

x[c("b", "d")]

關卡 70

關於R資料結構的入門就到這裡了。接下來,只要再學會對於矩陣和data.frame的操作,我們就可以開始解決實際的問題了!

關卡 71

最後我們想請同學試試看用今天所學的方法,整理台電的公開數據。請同學在完成之後存檔,並輸入submit()來檢查結果是否符合預期。如果同學在檔案中看到亂碼,請使用Rstudio左上角的File->ReopenWithEncoding…->選取:UTF-8

# 社會服務業自民國87至民國91年的年度用電量(度)
year1 <- 87:91
power1 <- c(6097059332, 6425887925, 6982579022, 7323992602.53436, 7954239517) 
# 製造業自民國87至民國91年的年度用電量(度)
power2 <- c(59090445718, 61981666330, 67378329131, 66127460204.6482, 69696372914.6949) 

# 請同學選出年度(`year1`)中,社會服務業的的用電量超過`7e9` 的年份。
# (`7e9`是R 的科學符號,代表`7 * 10^9`)
year1.answer1 <- year1[power1 > 7e9]

# 接著請同學計算「社會服務業從民國87年到91年的平均用電量」
power1.mean <- mean(power1)

# 請計算「社會服務業從民國87年到91年用電量的標準差」
power1.sd <- sd(power1)

# 在統計中,我們常常會計算一筆數據的「標準分數」,也就是將數據減去平均數後除以標準差。
# 請同學計算「社會服務業從民國87年到91年用電量的標準分數」
power1.z <- (power1 - mean(power1)) / sd(power1)

# 同樣的道理,請同學算出「製造業自民國87年至民國91年用電量的平均數、標準差和標準分數」
power2.mean <- mean(power2)
power2.sd <- sd(power2)
power2.z <- (power2 - mean(power2)) / sd(power2)

# 最後,請同學找出年度中,「社會服務業的用電量」,超過「製造業的10%用電量」的年份
year1.answer2 <- year1[power1 > 0.1 * power2]