這篇文章講R Lang中的資料物件。在R Lang中,資料物件可以是向量(vector)、矩陣(matrix)、陣列(array)、列表(lists)或資料框架(data frames)等。
矩陣 Matrix
矩陣是一個包含相同模式資料的二維度資料物件,大致相當於其他程式語言中的二維度數組的概念。
創建矩陣
使用函式matrix()
來創建矩陣物件。該函式的定義如下:
1 | matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL) |
下面我們來解釋其中的引數:
- nrow:正整數,設定列數(row numbers)
- ncol:正整數,設定欄數(column numbers)
- byrow:根據自動設定,欄位(column優先填滿)
- dimnames:輸入列表設定列名與欄位名
請中國大陸的讀者注意:在中國大陸和台灣,對於“行”和“列”的定義恰好是相反的。台灣地區的“行”或“欄”是指一個表格中的縱向(column),而“列”則是指一個表格中的橫向(row)。本文採用台灣地區的定義方式,敬請知曉。
使用dim()
函式可以回傳具有維度數屬性的資料物件之維度大小。
下面我們來看一個例子:
1 | ## 因為byrow預設為FALSE,因此遵循先欄後列的原則。 |
矩陣命名
矩陣的命名包括欄位名和列名。命名可以使用函式dimnames()
進行統一命名,也可以使用rownames()
函式或colnames()
單獨為列或欄命名。
1 | x.mat <- matrix(1:6, nrow = 2, ncol = 3) |
矩陣下標索引 Matrix Index
很像C++中的二維數組的下標。只不過在C++中,用到的是variable[i][j]
,而在R Lang中,使用variable[i, j]
而已。當然,與向量相同,該下標系統具有更強大的特性,一樣可以使用正整數、負整數等等。而如果想要取到一整列,可以使用variable[i, ]
即可。舉一反三,取到一整欄就是variable[, j]
。
1 | x <- matrix(c(1:12), nrow = 3, ncol = 4) |
我們可以看到,我們取到的只有一欄或一列的時候,會發生維度塌方,生成向量。而如果希望保持matrix的形式,則可以加入第三個引數drop = FALSE
。例如:
1 | x[1, , drop = FALSE] |
注意,和C家族語言中的無限for迴圈一樣,兩個逗號都不能省略,因為靠逗號來識別不同的引數。
向量與矩陣的合併
上一篇文章中我們提到,向量本身是沒有維度的。
一個比較簡單的方法是,將其重新定義為
1 | x.vec <- c(1:6) |
有時候我們需要把向量和矩陣或其他向量進行合併,成為一個新的矩陣,將該向量作為新矩陣的一欄或者一列。這時候,可以使用cbind()
函式或rbind()
函式。前者表示將向量作為新矩陣的一欄,後者則表示將向量作為新矩陣的一列。注意,如果向量的元素數量超過了矩陣的長度,則會報出一個Warning,然後捨棄掉超過的內容。如果不足,則會報出一個Warning,然後不足的內容開始重複填充,直到補足。
1 | x.vec <- c(1, 2, 3) |
陣列 Array
這個陣列和Java以及其他程式設計語言中的陣列完全不同。其他語言中的陣列等於數組,而在R Lang中,陣列是指包含相同模式 (mode) 的元素組成的p維資料物件。
陣列的操作基本和矩陣相同。使用array()
函式來創建陣列。函式定義如下:1
array(data = NA, dim = length(data), dimnames = NULL)
按照慣例解釋引數:
- dim:陣列的維度,以及每一個維度包含的元素個數。
- dimnames:每一個維度的命名。
一樣可以使用dimnames()
函式來為陣列的維度命名。rownames()
和colnames()
也同樣適用第一和第二維度。
關於下標系統,陣列和矩陣基本完全相同,只不過是有幾個維度上幾個引數而已。
由於篇幅原因,陣列部分就不放例子了。讀者可以自行回去試一下。
列表 List
R Lang中列表的概念也同樣不同於其他我們所熟悉的程式語言。在R Lang中,列表事實上就是一個有序的物件的集合體。特別注意的是,在前面介紹的無論是向量還是矩陣,抑或是陣列,都特別表明“包含相同模式 (mode)”。而列表中的元素(稱作“成分”,component)的模式則是所謂的複雜模式,即沒有限制。
列表的產生
使用list()
函式來產生列表。
通常情況下,我們先產生列表中的成分,再將成分組合成列表。
1 | x.vec <- 1:4 |
也可以在定義列表的時候,為每一個成分命名:
1 | x.num <- c(1, 3, 6) |
列表的下標與索引 List Index
列表的下標系統和向量、矩陣、陣列有所不同。當我們使用[]
的時候,取到的仍然是list模式的component,而不是我們塞進去的物件。要取到我們的物件,需要使用[[]]
。
1 | x.vec <- 1:4 |
若已經為成分命名,則可以使用成分名字來直接訪問到成分或其代表的物件。這裡有兩種方式,可以使用list.Name[["com.Name"]]
的傳統方式,也可以使用list.Name$com.Name
的方式。這兩種方式沒有任何區別。
1 | x.num <- c(1, 3, 6) |
資料框架 Data Frame
事實上,前面我們所講到的矩陣,我們可以把它看作是二維度表格,陣列則是多維度表格。然而,這些表格有一個限制,那就是元素的模式必須是相同的。
資料框架事實上也是一個二維表格,但與矩陣不同的是,它的元素模式可以是不同的。
創建資料框架
使用data.frame()
函式來創建資料框架。
1 | id.vec <- c(1, 2, 3, 4) |
資料框架的下標與索引 Data Frame Index
有兩套體系。一套是類似於矩陣的樣子,使用[i, j]
來獲取元素,另一套則是類似於列表,使用[[]]
來獲取成分中的物件。
1 | id.vec <- c(1, 2, 3, 4) |