第 5 章 Operation on vectors

5.1 Mathematical operations

曾意儒: 1.6.1-1.6.2

加、減、乘、除: +, -, *, /

a <- c(1, 5, -3)
b <- c(0.5, 12, 2)

試著練習a,b間的加減乘除

aL <- c(1L, 5L, -3L)
bL <- c(-2L, -4L, 8L)

請問a+bLaL+bL的class分別是什麼?如果用-*呢?

當運算的兩物件內容長度不同,但其中一個為只有一個元素值的純量時(即scalar),R會將運算視為elementwise operation。

c <- 4

c+a

餘數:%%

次方:^**

a^b
a %% b
twDateTime <- ymd_hms("2019-03-18 14:04:00", tz="Asia/Taipei")

twDateTime可以進行數字加減運算嗎?如果可以它是什麼意思?

請計算“2019-08-11”與“2000-02-01”的兩個日期的相減。相減完之後的值具有什麼class?

5.2 Operation on date time

Period: Add or subtract periods to model events that happen at specific clock times, like the NYSE opening bell.

Duration: Add or subtract durations to model physical processes, like battery life. Durations are stored as seconds, the only time unit with a consistent length.

startingDate <- ymd("2000-02-17")

明年此時(period)

startingDate + years(1)

經過整整一年(duration)

startingDate + dyears(1)

兩個時間相減一定是經過整整一段時間的duration概念。

ymd("2000-02-01") -> startingDate
ymd("2019-08-11") -> endingDate
endingDate - startingDate

5.3 Relational Operators

>,<,<=,>=: 分別為大於、小於、小於等於、大於等於

==: 等於

!=: 不等於

x <- 5
y <- 7
x2 <- c(1,5,10)
y2 <- c(-1,5,20)

==!=可使用於字串

x3 <- c("小明","小花")
y3 <- c("小明","小華")

還有一個常用的關連運算:

%in%: 屬於

x4 <- c(1,5,8)
y4 <- c(5,8)

x4 %in% y4
x5 <- c("台北市","新北市","高雄市")
y5 <- c("台北市","新北市")

x5 %in% y5

有時資料有缺失,在R裡會記成NA(即not available)如下例:

x2 <- c(1,NA,10)
y2 <- c(-1,NA,20)

x3 <- c(NA,"小花")
y3 <- c(NA,"小華")

前述的關係判斷遇到NA時,結果都會是NA——即無法判斷。要知道向量內各元素值是否NA,可使用is.na():

is.na(x2)

R還有一種特別的缺失資料NaN (即not a number),出現在沒有定義的數學運算上,如:

0/0

請先執行以下程式得到currency這個物件:

library(readr)
exData2 <- read_csv("https://raw.githubusercontent.com/tpemartin/github-data/master/exData2.csv")
currency <- exData2$幣別

請問這裡有幾種匯率? “日圓JPY/USD”匯率有多少筆資料(即有多少元素值是“日圓JPY/USD”)?

5.4 Logical Operators

針對class為logical之物件所進行之操作,主要有:

  • &: AND

  • |: OR

  • !: NOT (將T改F, F改T)

以下圖示,邊圈圈表示x為TRUE, 邊圈圈表示y為TRUE:

以下想像x5,y5分別代表三個人來自的都市,及性別。

x5 <- c("台北市","新北市","高雄市")
greatTaipei <- c("台北市","新北市")

x5 %in% greatTaipei
!(x5 %in% greatTaipei)
y5 <- c("女","男","女")

y5
y5=="女"
!(y5=="女")
(x5 %in% greatTaipei) & (y5=="女")
(x5 %in% greatTaipei) | (y5=="女")
xor(x5 %in% greatTaipei, y5=="女")

很多時候我們想知道向量中第幾筆元素資料為TRUE, 此時可用which():

y5
(y5 == "女")
which(y5=="女")

請先執行以下程式得到currency(幣別), date(日期), exchangeRate(匯率值)這些物件:

library(readr)
exData2 <- read_csv("https://raw.githubusercontent.com/tpemartin/github-data/master/exData2.csv")
date <- as.character(exData2$期間)
currency <- exData2$幣別
exchangeRate <- exData2$匯率
  • 請把date的class存成date class。

  • 1980-08-01之後的資料有多少筆。

  • 幣別為“歐元USD/EUR”的資料有多少筆。

  • exchangeRate有多少筆NA。

  • 排除NA後,幣別為“歐元USD/EUR”的資料有多少筆。

以上各題,請活用logical向量,也可以用sum來加總計算TRUE的個數。

請先執行以下程式得到grade (科目成績), courseType(課程為必/選或通識), major(學系),studentID(學號)物件,這些物件每一筆資料(即每個元素)是一位學生在一個科目的成績:

library(readr)
transcriptDataFinal <- read_csv("https://raw.githubusercontent.com/tpemartin/github-data/master/transcriptDataFinal.csv")
courseType <- transcriptDataFinal$`必選修類別(必∕選∕通)`
major <- transcriptDataFinal$學系
studentID <- transcriptDataFinal$學號
grade <- transcriptDataFinal$學期成績
  • 有多少筆資料是來自經濟學系

  • 請問學號“5bdS6977b”同學修了多少課。

  • 請問學號“5bdS6977b”有多少科成績及格。

  • 有多少筆資料來自經濟學系學生且為修課。

  • 經濟學系學生且修課程中,成績不及格佔多少比例。

5.5 Operation on Strings

Package: stringr

Download stringr cheat sheet

library(stringr)

It is common to operate on strings such as subset, join and split. Here we only talk about some of them. We will learn more later.

Subset
例如:選出course當中帶有“經濟學”的元素

course <- c("個體經濟學","投資學","總體經濟學")

Join
例如:將month和day合併成“3月11日”,“4月5日”,“2月7日”

month <- c("3","4","2")
day <- c("11","5","7")

Split
例如:將“3月11日”,“4月5日”,“2月7日”拆成如上的month, day

chineseDate <- c("3月11日","4月5日","2月7日")

Subset:依條件篩選

str_subset(): 保留字串向量元素裡符合某種規律(pattern)的向量元素——會縮小向量長度。

str_subset(course,"經濟學")

str_detect():偵測(detect)元素裡是否符合某種規律,若符合回TRUE, 不符合回FALSE

str_detect(course,"經濟學")

請在console視窗輸入?str_sub查詢str_sub()函數的使用方法,接著利用str_sub()取出以下每位學生系別及入學年。

studentID<-c(
  '410177115','410176080','410174233','410177011','410182045','410176014')

Join:合併

str_c(): 多個字串向量的合併

char1 <- c("月","月","月")
char2 <- c("日","日","日")
month
char1
day 
char2
str_c(month,char1,day,char2)
str_c(month,c("月"),day,c("日"))
str_c(month,"月",day,"日")

進行字串向量合併時,我們也可以自行決定要不要加分隔(separation)符號:

month
day
str_c(month,day, sep="-")

Split:分割

str_split(): 分割一個字串向量(後面章節再詳述)

dates <- c("3-11", "4-5",  "2-7")
str_split(dates,"-")

Replace: 取代

str_replace()

dates
str_replace(dates,"-","月")

str_replace_all()

dates2 <- c("3-11-2019", "4-5-2017",  "2-7-2015")
dates2
str_replace(dates2,"-","/")
str_replace_all(dates2,"-","/")

每個GitHub repo都有一個固定的網址型式,如: https://github.com/tpemartin/107-2-inclass-practice 其中:

  • tpemartin: username

  • 107-2-inclass-practice: repo name

執行以下程式引入資料

library(readr)
githubData <- read_csv("https://raw.githubusercontent.com/tpemartin/github-data/master/githubData.csv")
username <- githubData$`GitHub username`[11:16]
reponame <- githubData$`GitHub repo name`[11:16]

將username與reponame合併成Github repo網址。

5.6 綜合練習

練習1

資料來源: 第三屆經濟播客競賽人氣投票結果

請先執行以下程式引入資料:

library(readr)
filmVotingData <- read_csv("https://raw.githubusercontent.com/tpemartin/github-data/master/%E7%AC%AC%E4%B8%89%E5%B1%86%E7%B6%93%E6%BF%9F%E6%92%AD%E5%AE%A2%E7%AB%B6%E8%B3%BD%E5%8F%83%E8%B3%BD%E4%BD%9C%E5%93%81%E6%8A%95%E7%A5%A8%E7%B5%90%E6%9E%9C%E6%A8%A3%E6%9C%AC%20-%20Sheet1.csv")
birthday<-filmVotingData$`出生西元年月日(驗證本人用)`

試著將birthday變成“西元yyyy年mm月dd日”型式。

練習2 Taiwan date-time

台灣的資料常為民國年月,又因為其資料記載方式,初次引入的年月資料常如下所示:

民國年月<-c("099/01","099/02","099/03")

將上述資料轉成西元年月格式(民國年+1911即為西元年)的date class。你的程式設計策略為何?

(hint: date class的變數可以用+years(k)把西元年增加k年。同學也可以查查lubridate::years()用法)

線上練習

線上練習網址:https://garylkl.shinyapps.io/Chapter4/