上週實習課使用 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 FALSE
boolean operators (&
, |
, !
, any()
, all()
) 可以整合多個 logical tests
#> [1] TRUE
#> [1] FALSE
#> [1] TRUE
#> [1] FALSE
#> [1] TRUE
NA
代表的是「缺失值」,可以作為任何一種 vector 裡面的元素。當 NA
出現在 vector 中,函數對於 vector 的運算常會出現令人意外的結果:
#> [1] NA
#> [1] NA
#> [1] NA
#> [1] 2
c(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!"
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."