本篇介紹 R 的列表變數與 data frames 的使用方式。

R 列表變數

R 的列表(list)變數類似向量,內含多個元素,不過跟向量不同的是列表是一種復合型的變數,其中的每個元素可以是不同的類型,我們可以將各式各樣不同類型的變數儲存在一個列表變數中。

建立列表變數

列表變數可以使用 list 函數來建立,而其內容的指定方式跟 c 函數類似,但 list 可以允許各種不同類型的資料混合使用,例如向量、矩陣、字元變數等,甚至是函數也可以:

x.list <- list(1:3, "G.T.Wang", matrix(3:6, nrow = 2), sin)
x.list
[[1]]
[1] 1 2 3

[[2]]
[1] "G.T.Wang"

[[3]]
     [,1] [,2]
[1,]    3    5
[2,]    4    6

[[4]]
function (x)  .Primitive("sin")

我們也可以為列表的每個元素命名:

x.list <- list(
  seq = 1:3,
  name = "G.T.Wang",
  mat = matrix(3:6, nrow = 2),
  fun = sin)
x.list
$seq
[1] 1 2 3

$name
[1] "G.T.Wang"

$mat
     [,1] [,2]
[1,]    3    5
[2,]    4    6

$fun
function (x)  .Primitive("sin")

或是在建立列表之後,再使用 names 函數指定每個元素的名稱:

names(x.list) <- c("seq", "name", "mat", "fun")

列表變數的元素中也允許納入其他的列表變數,形成巢狀的資料結構:

y.list <- list(
  var1 = list( name = "pi", val = pi),
  var2 = list( name = "e", val = exp(1))
)
y.list
$var1
$var1$name
[1] "pi"

$var1$val
[1] 3.141593


$var2
$var2$name
[1] "e"

$var2$val
[1] 2.718282

列表的巢狀結構層數並沒有什麼限制,不管要建立幾層都沒問題。

如果列表的巢狀結超過數萬層以上,R 可能會產生錯誤訊息,不過這個限制在實際的情況下不太容易發生。

列表變數的索引

列表變數跟一般的向量一樣可以使用 [] 來存取其中的元素,可使用的索引類型有正整數、負整數、邏輯向量或元素名稱:

x.list[1:3]
$seq
[1] 1 2 3

$name
[1] "G.T.Wang"

$mat
     [,1] [,2]
[1,]    3    5
[2,]    4    6
x.list[-4]
$seq
[1] 1 2 3

$name
[1] "G.T.Wang"

$mat
     [,1] [,2]
[1,]    3    5
[2,]    4    6
x.list[c(TRUE, TRUE, TRUE, FALSE)]
$seq
[1] 1 2 3

$name
[1] "G.T.Wang"

$mat
     [,1] [,2]
[1,]    3    5
[2,]    4    6
x.list[c("seq", "name", "mat")]
$seq
[1] 1 2 3

$name
[1] "G.T.Wang"

$mat
     [,1] [,2]
[1,]    3    5
[2,]    4    6

以上幾種存取方式所得到的結果都會是一個新的列表變數,如若希望取得一個元素並保持原有的型態,可以改用 [[]] 運算子,這個運算子可以使用正整數或元素名稱來提取對應的列表元素:

x.list[[2]]
[1] "G.T.Wang"
x.list[["name"]]
[1] "G.T.Wang"

對於有名稱的列表元素,也可以使用錢字號運算子($)加上元素名稱來存取:

x.list$name
[1] "G.T.Wang"

使用錢字號運算子的方式跟 [[]] 運算子一樣也可以保留元素原本的型態,而且還有其他的優點,例如在 R 中打字的時候,我們可以輸入元素名稱的開頭幾的字母,再按下 Tab 鍵讓 R 自動補齊剩餘的名稱,另外 R 也允許使用名稱開頭的幾個字母來存取元素(前提是輸入的字母要讓 R 足以辨識要指定的元素):

x.list$n
[1] "G.T.Wang"

巢狀的列表結構可以使用多個 [[]][] 運算子堆疊來存取,常見的方式有以下幾種:

y.list[[1]][2]
$val
[1] 3.141593
y.list[["var1"]]["val"]
$val
[1] 3.141593
y.list[[1]][[2]]
[1] 3.141593
y.list[["var1"]][["val"]]
[1] 3.141593
y.list[[c(1, 2)]]
[1] 3.141593
y.list[[c("var1", "val")]]
[1] 3.141593