迷你課程:R語言-3~list, matrix與array的子集提取

Quick look

今天介紹R中如何對 List、Matrix和Array(陣列)進行子集提取(Subsetting)的操作,包含:

  1. 列表的多種提取方式。
  2. 矩陣基本子集提取方法。
  3. 陣列的多維子集提取技巧。

List的子集提取

先建立一個list

my_list <- list(
  Name = "Yang-Hong",
  Age = 35,
  Scores = c(85.5, 90.2, 78.9),
  Matrix = matrix(1:9, nrow = 3)
)
#>
$Name
[1] "Yang-Hong"

$Age
[1] 35

$Scores
[1] 85.5 90.2 78.9

$Matrix
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

提取list的元素:

# 使用名稱提取
my_list$Name  # "Yang-Hong"

# 使用雙中括號提取
my_list[["Age"]]  # 35

# 使用數字索引
my_list[[3]]  # [85.5 90.2 78.9]

注意上面數字索引的部分需要用[[]]才能完整將元素取出,如果只用[]也可以取出來物件,但是會帶有list的結構。 同理名稱索引也會有一樣的情況。


提取子列表

但若是要提取一個子列表,就可以用數字加上[]:

# 提取一個子列表,提取第一個與第二個元素,返回結構仍是一個list
sub_list <- my_list[1:2]

鑲嵌提取

如果列表中的元素是更複雜的數據結構,可以進行鑲嵌提取:

# 提取 Matrix 中的第一列
my_list$Matrix[1, ]  # [1 4 7]

另外要注意的是,$支援partial matching,但[[]]不行,因此用[[]]會比較不會出錯。


Matrix的子集提取

矩陣是一個2維數據結構,僅允許存儲相同類型的數據。可以通過行和列進行子集提取。 先建立一個matrix:

# 建立一個 3x3 的矩陣
mat <- matrix(
  data = 1:9,
  nrow = 3, #根據data長度來調整行與列的數量
  ncol = 3,
  byrow = TRUE #決定依循row方向排列與否。
)
#>
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9

提取單個元素

# 提取第一行第一列的元素
mat[1, 1]  # [1]

提取整行或整列

# 提取第二列
mat[2, ]  # [4 5 6]

# 提取第三行
mat[, 3]  # [3 6 9]

提取子矩陣

# 提取第一到第二行,第二到第三列的子矩陣
sub_mat <- mat[1:2, 2:3]

得到:

#>

 [2 3]
 [5 6]

保持matrix結構

一般直接取出matrix的整列或整行會得到atomic vector,但若要維持matrix的結構,可以加上參數drop=FALSE:

mat[, 3, drop=FALSE] 

得到:

#>
     [,1]
[1,]    3
[2,]    6
[3,]    9

邏輯條件提取

可以使用邏輯條件篩選矩陣中的特定元素:

# 找出矩陣中大於5的元素
mat[mat > 5]  # [7 8 6 9]

# 設定條件篩選
selected <- mat[mat %% 2 == 0]  # 提取偶數

搭配which()

使用which()可以得到符合邏輯條件的元素位置在哪。

which(mat>5)
#>
[1] 3 6 8 9 #表示在這些位置元素的值>5

上面的位置是順著column來數,所以第三個位置落在第一行第三列,數值為7且大於5,第8個位置落在第三行第二列,數值為6且大於5。

我們也可以再用這些返回的位置將數值取出來:

mat[which(mat>5)]
#>
[1] 7 8 6 9

然而如果希望取出來的位置或index可以給我們行列的配對,在使用which()的時候可以加上arr.ind=TRUE

which(mat>5, arr.ind=TRUE)

會得到確切的行列位置:

#>
     row col
[1,]   3   1
[2,]   3   2
[3,]   2   3
[4,]   3   3

而這個返回的數據為matrix的結構,而matrix可以當成索引的條件來找出矩陣裡面相對應的元素。

同樣的道理,如果今天有兩個索引向量一個代表row,一個代表column,用cbind()結合起來的結構也是matrix,也可以丟回去來索引matrix中某row某column的數值。這個在分析基因序列建立矩陣時可能會用到,當成one-hot encoding的方式之一。


Array的子集提取

陣列是R中的多維數據結構,可以具有多於兩個維度。子集提取時可以按多維索引操作。

建立array

# 建立一個3x3x2的三維陣列
arr <- array(
  data = 1:18,
  dim = c(3, 3, 2) #代表有兩層,每一層維度=3x3
)
#>
 第一層:
     [,1] [,2] [,3]
 [1,]    1    4    7
 [2,]    2    5    8
 [3,]    3    6    9

 第二層:
     [,1] [,2] [,3]
 [1,]   10   13   16
 [2,]   11   14   17
 [3,]   12   15   18

提取單個元素

# 提取第一層第一行第二列的元素
arr[1, 2, 1]  # [4]

提取整列或整行

# 提取第二層的第三行
arr[, 3, 2]  # [16 17 18]

# 提取第一層的第二列
arr[2, , 1]  # [2 5 8]

提取特定切片

# 提取第一層的所有數據
slice <- arr[, , 1]

邏輯條件提取

array也可以進行邏輯條件選取。

# 找出所有大於10的元素
arr[arr > 10]  # [11 12 13 14 15 16 17 18]

# 選擇特定條件的子陣列
selected <- arr[arr %% 3 == 0]

課程小結

資料結構特性提取範例
List可儲存不同型態數據,靈活提取多層結構my_list[["Name"]]
Matrix二維結構,行列提取mat[1, 2]
Array多維結構,支援多層提取arr[1, 2, 3]
Yang-Hong Dai 戴揚紘
Yang-Hong Dai 戴揚紘
主治醫師

我的研究興趣為結合數據分析來探討各種癌症生物學。

comments powered by Disqus