我們在約維安計畫:建立基本資料單位「向量」中已經知道 R 語言的基本資料單位稱作向量(vector
),透過結合基本資料單位,能夠組成其他的資料結構,這些資料結構包含彈性的容器:清單(list
)、有階層資訊的向量:因素向量(factor
)、現代化表格:資料框(data.frame
)、二維向量:矩陣(matrix
)與多維向量:陣列(array
)。
彈性的容器:清單
我們目前熟悉的向量只能被宣告為單一類型,這是為了元素運算(Elementwise operation)而伴隨的侷限,然而在應用上很多不同類型的資料有被儲存在同一個物件中的需求,這時候我們就可以使用 list
資料結構儲存任何類別、長度的向量,使用 list()
函數建立彈性的容器:清單。
a_R_list <- list(
c(FALSE, TRUE),
c(55L, 66L, 56L, 5566L),
c(55, 66, 56, 5566),
c("Some", "random", "characters")
)
print(a_R_list)
print(class(a_R_list))
清單強大的收納能力用數個雙層中括號 [[]]
將各個向量依順序放入一個物件之中,這時候要選擇裡面的向量,就改使用雙層中括號 [[索引值]]
,在這個清單之中,我們儲存了四個不同類型的向量,依序是長度 2 的邏輯向量、長度 4 的整數向量、長度 4 的數值向量、長度 3 的文字向量,在清單中各個向量依然保有自己的類別。
print(class(a_R_list[[1]]))
print(class(a_R_list[[2]]))
print(class(a_R_list[[3]]))
print(class(a_R_list[[4]]))
建立清單的同時,如果我們有給予向量一個對應的鍵(Key),可以在選擇時改使用 [["key"]]
或 $key
,這時面對的是有命名的清單(Named list)。
a_R_list <- list(
logicals = c(FALSE, TRUE),
integers = c(55L, 66L, 56L, 5566L),
numerics = c(55, 66, 56, 5566),
characters = c("Some", "random", "characters")
)
# use [["key"]]
print(class(a_R_list[["logicals"]]))
print(class(a_R_list[["integers"]]))
print(class(a_R_list[["numerics"]]))
print(class(a_R_list[["characters"]]))
# use $key
print(class(a_R_list$logicals))
print(class(a_R_list$integers))
print(class(a_R_list$numerics))
print(class(a_R_list$characters))
有階層資訊的向量:因素向量
R 語言針對文字向量有一個額外的資料結構稱為因素向量,這是一種具有層級(Levels)資訊的向量,我們可以使用 factor()
函數將一般的文字向量轉換成因素向量。
four_seasons <- c("spring", "summer", "autumn", "winter")
print(class(four_seasons))
four_seasons_factor <- factor(four_seasons)
print(class(four_seasons_factor))
print(four_seasons_factor)
印出因素向量時會將層級的資訊輸出,預設的層級是以字母順序排列(由 A 排至 Z),而在轉換為因素向量的函數 factor()
之中利用 ordered
與 levels
參數可以依照使用者的偏好做排列。
four_seasons_factor <- factor(four_seasons, ordered = TRUE, levels = c("autumn", "spring", "winter", "summer"))
print(four_seasons_factor)
現代化表格:資料框
資料框是 R 語言用來處理表格式資料(tabular data)的資料結構,它的外觀具有列與欄兩個維度,具備列索引值與欄索引值來支援使用者,並容許每一個欄位(變數)具有自己的類別,使用 R 語言讀取外部地表格式資料也會以資料框的結構儲存,我們可以運用 data.frame()
函數創造資料框。
titles <- c("Batman Begins", "The Dark Knight", "The Dark Knight Rises")
release_years <- c(2005, 2008, 2012)
imdb_ratings <- c(8.2, 9.0, 8.4)
is_on_netflix <- c(TRUE, FALSE, TRUE)
batman_trilogy <- data.frame(title = titles, release_year = release_years, imdb_rating = imdb_ratings, is_on_netflix)
print(batman_trilogy)
print(class(batman_trilogy))
我們使用觀測值(observations)來稱呼資料框中水平方向的資料,使用變數(variables)來稱呼資料框中垂直方向的資料;資料框能夠以 [m, n]
兩個索引值來搭配選擇,其中 m
是資料框的觀測值個數, n
是資料框的變數個數,一個資料框的外觀可以簡潔地以 (m, n) 來描述,例如手動創建的資料框 batman_trilogy
外觀為 (3, 4),透過 dim() 函數來暸解資料框的外觀。
print(dim(batman_trilogy))
print(batman_trilogy[1, ]) # data in the 1st row
print(batman_trilogy[, 1]) # data in the 1st column
print(batman_trilogy[1, 1]) # data at (1, 1)
資料框支援使用變數名稱來選擇,我們可以用 $variable_name、[["variable_name"]]
或者 [, "variable_name"]
這三種寫法。
print(batman_trilogy$title)
print(batman_trilogy[["title"]])
print(batman_trilogy[, "title"])
我們可以透過邏輯向量來對資料框進行篩選,要注意篩選是針對觀測值(水平方向),所以要將邏輯向量放在逗號前面,逗號後面留空(並沒有要選擇變數。)
print(batman_trilogy[batman_trilogy$is_on_netflix, ])
資料框能包含多種向量類別,可以透過 str()
函數(structure 的縮寫)檢視組成資料框的向量類型。
print(str(batman_trilogy))
資料科學家花費很多的時間與資料框周旋,常應用於探索資料框的函數以及進階的資料框操控技巧會在後續詳細探討。
二維向量:矩陣
矩陣與資料框相同是能夠儲存列(Row)與欄(Column)的資料結構,如果對於分辨行、列與欄這些中文字有障礙的話,我非常推薦用英文來記憶:Row 指的是水平方向資料,Column 指的是垂直方向資料。通用的習慣是先列後欄,假如我們現在要建立一個 (2, 3) 的矩陣,意思就是兩個水平方向搭配三個垂直方向的矩陣。使用 matrix()
函數並指定參數 nrow = 2
將向量轉換成一個 (2, 3) 的矩陣;往後如果聽到一個矩陣是 (m, n) 的外觀,我們心中就會知道,這個矩陣具有 m 個水平方向資料,n 個垂直方向資料。
a_R_matrix <- matrix(c(5, 6, 55, 66, 56, 5566), nrow = 2)
print(a_R_matrix)
print(class(a_R_matrix))
矩陣同樣能夠以 []
搭配索引值選出裡面的變數,不過跟向量不同的是現在有兩個維度的索引值必須指定,所以要用 [m, n]
兩個索引值來搭配選擇。
print(a_R_matrix[2, 3]) # data at (2, 3)
print(a_R_matrix[2, ]) # data in the 2nd row
print(a_R_matrix[, 3]) # data in the 3rd column
我們也可以透過邏輯向量來對矩陣進行篩選。
print(a_R_matrix[a_R_matrix > 10])
多維向量:陣列
陣列是向量、矩陣的多維度版本,除了原有的水平方向資料(Row)與垂直方向資料(Column)我們可以再多指定 n 個維度,簡單來說,就是在一個陣列的物件之中,可以允許儲存多個矩陣。舉例來說我們就可以用陣列將 1 到 24 這 24 個數字儲存在 4 個 (2, 2) 的矩陣之中。
a_R_array <- array(1:24, dim = c(2, 3, 4))
print(a_R_array)
print(class(a_R_array))
因為有了三個維度,所以在使用索引值選擇時,就需要增加第三個維度的索引值。
print(a_R_array[1, 2, 3]) # data at (1, 2, 3)
print(a_R_array[1, , 3]) # data in the 1st row of the 3rd matrix
print(a_R_array[, 2, 1]) # data in the 2nd column of the 1st matrix
在初步暸解如何在 R 語言其他的資料結構之後,本篇文章來到尾聲,希望您也和我一樣期待下一篇文章。
延伸閱讀
對於這篇文章有什麼想法呢?喜歡😻、留言🙋♂️或者分享🙌