上週實習課使用 R 時,指令的回傳值多半只有「一個」。但 R 其實是一種以向量作為基本單位的程式語言,所以對於「一個回傳值」更精確的描述應該是「一個長度為 1 的向量」。
#> [1] 2
#> [1] TRUE
#> [1] 1我們上週簡短提過以 : 製造數列的方式 (e.g. 1:10)。事實上,這個回傳的數列即是一個 vector。另外,由於這個 vector 的每個元素皆是整數,因此這個 vector 屬於 integer vector。我們可以使用 typeof() 確認 vector 的類別
#> [1] "integer"R 裡面的 vector 可以被分成 6 種類別,其中常見的 4 種分別為 integer, double, , character, logical
: 製造數列,也可以使用 c() (稱為 concatenate) 組出任意序列的 vector。
c() 製造 integer vector 時,每個整數數字後面必須接 L,若沒有加上 L, R 會將製造出來的 vector 視為 double vector。#> [1] -1 5 2
#> [1] -1 5 2
#> [1] "integer"
#> [1] "double"
double vector 儲存的是浮點數,亦即含有小數點的數字 (e.g 1.2, -0.75)
在 R 裡面,integer vector 與 double vector 合稱為 numeric vector,兩者之間的區隔通常也不太重要,因為 R 在運算時,通常會將這兩種資料類型自動轉換成合適的類型
#> [1] "integer"
#> [1] "double"
#> [1] TRUE
#> [1] TRUE
#> [1] "double"
#> [1] "double"Inf: 代表無限大NaN: “Not a Number”,常見於數字運算不符數學定義時,例如:
#> Warning in log(-1): NaNs produced
#> [1] NaN
#> [1] NaN
#> [1] NaN除了數字以外,R 也可以儲存字串 (string)。character vector 的每個元素皆由一個字串所組成。在 R 裡面,只要是被引號 (quote, ' 或 " 皆可) 包裹的東西就是字串,放在引號內的可以是任何字元 (e.g. 空白、數字、中文字、英文字母)
#> [1] "1.1"
#> [1] "你 好!"
#> [1] "1.1" "你 好!"",需在字串內的引號前使用跳脫字元 \,以表示此引號是字串的一部分而非字串的開頭或結尾
"\"" # escape a double quote
'\'' # escape a single quote
'"' # a double quote as string without escaping
"'" # a single quote as string without escaping#> [1] "\""
#> [1] "'"
#> [1] "\""
#> [1] "'"logical vector 的每個元素由 TRUE 或 FALSE 組成。
可以使用 c() 一項項手動輸入製造 logical vector
==, !=, >, <, %in%#> [1] FALSE TRUE FALSE
#> [1] TRUE FALSE TRUE
#> [1] FALSE FALSE FALSEboolean operators (&, |, !, any(), all()) 可以整合多個 logical tests
#> [1] TRUE
#> [1] FALSE
#> [1] TRUE
#> [1] FALSE
#> [1] TRUENA 代表的是「缺失值」,可以作為任何一種 vector 裡面的元素。當 NA 出現在 vector 中,函數對於 vector 的運算常會出現令人意外的結果:
#> [1] NA
#> [1] NA
#> [1] NA
#> [1] 2c(1, 2, 3) + 2, R 會自動將長度較短 vector (2) 「回收 (recycle)」,亦即,重複此向量內的元素使其「拉長」到與另一個 vector 等長;接著再將兩個一樣長的 vector 進行 element-wise 的向量運算。#> [1] 3 3 4 4
#> [1] 3 3 4 4
#> [1] FALSE FALSE TRUE TRUE
#> [1] FALSE FALSE TRUE TRUE
#> [1] "a1"
#> [1] "a1" "b1" "c1"
vector 內的每個元素,其資料類型 (data type) 必須相同。資料類型即是前面提到的 integer, double, character, logical。
若發生資料類型不一致的情形 (e.g. 將不同資料類型的元素放入 c()),R 會根據某些規則,自動進行資料類型的轉換。這個過程在 R 裡面稱為 Coercion
c(TRUE, FALSE, 3) # logical & numeric
c(-1, "aa") # numeric & character
c(FALSE, TRUE, "hi!") # logical & character
c(TRUE, 0, "hi!") # logical & numeric & character#> [1] 1 0 3
#> [1] "-1" "aa"
#> [1] "FALSE" "TRUE" "hi!"
#> [1] "TRUE" "0" "hi!"Rules of Coercion
if coercion failed, throw error
manual coercion: as.character(), as.logical(), as.numeric()
sum(c(T, T, T, F))
gender <- c("male", "female", "male", "female")
sum(gender == "male") # num of male
mean(gender == "male") # proportion of male#> [1] 3
#> [1] 2
#> [1] 0.5
TRUE 或 FALSE 表示是否保留該位置的元素names 屬性)#> [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q"
#> [18] "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
#> [1] "A"
#> [1] "A" "B" "C" "D" "E"
#> [1] "A" "C" "E"
#> [1] "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V"
#> [18] "W" "X" "Y" "Z"
#> [1] 20 19
#> [1] FALSE
#> [1] FALSE FALSE TRUE TRUE
#> [1] 18 19
age <- c(40, 20, 18, 19)
names(age) <- c("kai", "jessy", "joy", "yola")
# age <- c(kai = 40, jessy = 20, joy = 18, yola = 19) # another way of setting names
age#> kai jessy joy yola
#> 40 20 18 19
#> kai
#> 49
#> jessy kai
#> 20 40
#> [1] "a" "b" "c" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q"
#> [18] "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
#> [1] "male" "male" "f" "f"
#> [1] "male" "male" "female" "female"
#> john jenny jane kate
#> "male" "male" "female" "female"
#> john jenny jane kate
#> "male" "male" "female" "female"
#> john jenny jane kate
#> "male" "female" "female" "female"
#> [1] "x is positive"
x <- -1
if (x > 0) {
print('x is positive')
} else if (x < 0) {
print('x is negative')
} else {
print('x is zero')
}
print('This is always printed')#> [1] "x is negative"
#> [1] "This is always printed"
在 if-else if-else 的結構中,只有其中一個區塊 (被大括弧 {} 包裹的程式碼) 會被執行。執行完該區塊後,就會忽略剩下的條件控制區塊,執行條件式之後的程式碼。
可以在 if 之後使用多個 else if.
條件式的結構:
# Data
name <- c("kai", "jessy", "joy", "yola")
age <- c(40, 20, 18, 19)
about <- c("a professor", "a cat lover", "a hacker", "a YouTuber")
# Randomly draw 2 subjects
draws <- sample(1:4, size = 2)
# Find out who is older
if (age[draws[1]] > age[draws[2]]) {
comparitive <- 'is older than'
} else if (age[draws][1] < age[draws][2]) {
comparitive <- 'is younger than'
} else {
comparitive <- 'is the same age as'
}
# Construct sentence
roles <- paste0(name[draws], ", " , about[draws])
roles#> [1] "yola, a YouTuber" "joy, a hacker"
#> [1] "yola, a YouTuber, is older than joy, a hacker."