R的資料結構還有指令非常複雜,但大多是與統計有關,所以看不懂的就跳過去別看了,只需要學有用到的就可以了。
基本的資料結構:Vector, Array, List, Data Frame
Vector
一串數字或文字...,用c(...)建立,如c(3,5,100)就是建立3,5,100三個數字串列
對於 vectot 的操作,可有 min(), max(), sort()...等
> a=sample(18) #隨機產生18個數字
> a
[1] 4 7 5 3 13 16 11 2 17 10 9 15 8 18 1 14 6 12
> b<-sort(a)
> b
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
> min(a)
[1] 1
> max(a)
[1] 18
Array
向量只有在定義了dim屬性後才能作為陣列在 R 中使用。假定,z是一個含1500 個元素的向量。那麼
> dim(z) <- c(3,5,100)
對 dim 屬性的賦值使得該向量成一個 3 × 5 × 100 的陣列。
資料向量的值在陣列中的排列順序採用 FORTRAN 的陣列元素次序,即“按列次序”,也就是說第一下標變化最快,最後下標變化最慢。
假定陣列a的維數向量是 c(3,6),則 a 中有 3 * 6 = 18元素,依次為 a[1,1], a[2,1], ..., a[1,6], a[2,6],a[3,6]。
> a=sample(18) #隨機產生18個數字
> a
[1] 9 13 12 5 16 10 4 3 2 17 6 11 18 1 7 8 15 14
> dim(a)=c(3,6) # 把 a 從 Vector 變成 array (3,6)
> a #觀看排列順序,a[1,1]=9,a[2,1]=13, a[3,1]=12
[,1] | [,2] | [,3] | [,4] | [,5] | [,6] | |
[1,] | 9 | 5 | 4 | 17 | 18 | 8 |
[2,] | 13 | 16 | 3 | 6 | 1 | 15 |
[3,] | 12 | 10 | 2 | 11 | 7 | 14 |
> b[,]
|
[,1] |
[,2] |
[,3] |
[,4] |
[,5] |
[,6] |
[1,] |
4 |
3 |
11 |
10 |
8 |
14 |
[2,] |
7 |
13 |
2 |
9 |
18 |
6 |
[3,] |
5 |
16 |
17 |
15 |
1 |
12 |
> b[1,]
[1] 4 3 11 10 8 14
> b[,1]
[1] 4 7 5
> x <- array(1:20, dim=c(4,5)) # 產生一個 4 × 5 的陣列。 #1:20即1,2,...20
> x
x |
[,1] |
[,2] |
[,3] |
[,4] |
[,5] |
[1,] |
1 |
5 |
9 |
13 |
17 |
[2,] |
2 |
6 |
10 |
14 |
18 |
[3,] |
3 |
7 |
11 |
15 |
19 |
[4,] |
4 |
8 |
12 |
16 |
20 |
> i <- array(c(1:3,3:1), dim=c(3,2)) # 1:3=1,23;3:1=3,2,1
> i # i 是一個 3 × 2 的索引矩陣。
i |
[,1] |
[,2] |
[1,] |
1 |
3 |
[2,] |
2 |
2 |
[3,] |
3 |
1 |
> x[i] # 提取這些元素。#及 x[1,3], x[2,2],x[3,1]
[1] 9 6 3
> x[i] <- 0 # 用0替換這些元素。
> x
x |
[,1] |
[,2] |
[,3] |
[,4] |
[,5] |
[1,] |
1 |
5 |
0 |
13 |
17 |
[2,] |
2 |
0 |
10 |
14 |
18 |
[3,] |
0 |
7 |
11 |
15 |
19 |
[4,] |
4 |
8 |
12 |
16 |
20 |
>
List
List是一個以物件的有序集合構成的物件。List中包含的物件又稱為它的分量(components)。
分量可以是不同的模式或者類型,如一個列表可以包括數值向量,邏輯向量,矩陣,複向量,字元陣列,函數等等。下面是一個例子演示怎麼創建列表:
> Lst <- list(name="Fred", wife="Mary", no.children=3, child.ages=c(4,7,9))
分量常常會被編號的(numbered),並且可以利用它來訪問分量。如果向量Lst
有四個分量,這些分量可以用 Lst[[1]]
, Lst[[2]]
, Lst[[3]]
和 Lst[[4]]
獨立訪問。如果 Lst[[4]]
是一個有下標的陣列,那麼 Lst[[4]][1]
就是該陣列的第一個元素了。
因為 Lst
是一個列表,所以函數 length(Lst)
給出的僅僅是分量的數目(最高層次的)。
列表的分量可以被命名,這種情況下可以通過名字訪問。這時,可以把字串形式的分量名字放在列表名後面的雙中括弧中,或者乾脆採用下面的形式
> name$component_name
完成一樣的目的。
這種方法非常有用。使你在忘記分量編號的時候,可以很容易找到想要的東西。
因此在上面給定的例子中,
Lst$name
和 Lst[[1]]
返回結果都是 "Fred"
,
Lst$wife
和 Lst[[2]]
返回的則是 "Mary"
,
而Lst$child.ages[1]
和 Lst[[4]][1]
返回一樣的數字 4
。
另外你同樣可以在雙中括弧中使用列表分量的名字,也就是和Lst$name
等價的 Lst[["name"]]
。當分量的名字保存在另外一個變數中時,這種方法特別的有用。就如下面的例子所示
> x <- "name"; Lst[[x]]
特別要注意一下 Lst[[1]]
和 Lst[1]
的差別。 [[
...]]
是用來選擇單個元素的操作符,而 [
...]
是一個更為一般的下標操作符。 因此前者得到的是列表 Lst
中的第一個物件, 並且含有分量名字的命名列表(named list)中分量的名字會被排除在外的。後者得到的則是列表 Lst
中僅僅由第一個元素構成的子列表。如果是命名列表,分量名字會傳給子列表的。
分量名字可以簡寫1,原則是只要能很好的區分所有分量就行。因此 Lst$coefficients
可以簡寫為 Lst$coe
而 Lst$covariance
可以簡寫成 Lst$cov
。
名字向量(記錄分量名字的向量)實際上可以簡單地看作是列表的一個屬性,可以像其他屬性一樣操作。除了列表,其他的結構物件也可能會給出一個相似的名字屬性。
和其他所有被下標索引的物件一樣,列表是可以擴充分量的。如
> Lst[5] <- list(matrix=Mat)
data frame
資料框(data frame)是一個含有 "data.frame"
類的列表。
6.3.1 創建資料框
可以通過函數data.frame 創建符合上面對列(分量)限制的資料框對象:
> accountants <- data.frame(home=statef, loot=incomes, shot=incomef)
符合資料框限制的列表可被函數 as.data.frame() 強制轉換成資料框。 從外部檔讀取一個資料框最簡單的方法是使用函數 read.table()。這個將在 Reading data from files 部分詳細討論。
6.3.2 attach() 和 detach()
用 $ 符號訪問物件不是非常的方便,如accountants$statef。一個非常有用的想法就是讓列表或者資料框的分量可以通過它們的名字直接調用。而且這種調用是暫時性的,只是沒有顯式的引用列表名字。
函數 attach() 除了可以用目錄路徑作為參數,也可以使用資料框。假定數據框 lentils 有三個變數 lentils$u, lentils$v, lentils$w,那麼
> attach(lentils)
將把資料框綁定在搜索路徑的位置2(position 2)上1。如果位置1沒有變數 u, v 或 w,那麼 u, v 和 w 可以直接在資料框中訪問。此時,下麵的命令
> u <- v+w
這個命令實際上沒有替換資料框中的變數 u,而是被處於搜索路徑位置 1的工作空間中的變數 u 所遮罩。為了真正改變資料框中的資料,最簡單的辦法還是使用 $ 符號:
> lentils$u <- v+w
但是新的分量 u 是不可見的,直到資料框綁定去除或者重新綁定。
去除一個資料框的綁定,可以使用
> detach()
確切地說,該命令去掉了搜索路徑中與位置 2的綁定。此時, u, v 和 w 將不再可見,但可以用 lentils$u 類似的命令來查看這些變數。如果實體所處的環境位置值大於2,則可以通過把位置值直接傳給detach的辦法實現綁定去除,不過,最為安全的辦法是直接使用名字,如 detach(lentils) 和 detach("lentils")
read.table()
函數
為了可以直接讀取整個資料框,外部檔常常要求有特定的格式。
- 第一行可以有該資料框各個變數的 名字。
- 隨後的行中第一個條目是行標籤,其他條目是各個變數的值。
在檔中,第一行比第二行少一個條目,這樣做是被強制要求的1。因此一個被看作資料框讀入的檔開頭幾行應該是下面的形式。
有列名字和行標籤的輸入檔格式: Price Floor Area Rooms Age Cent.heat 01 52.00 111.0 830 5 6.2 no 02 54.75 128.0 710 5 7.5 no 03 57.50 101.0 1000 5 4.2 no 04 57.50 131.0 690 6 8.8 no 05 59.75 93.0 900 5 1.9 yes ...
默認情況下,數值項(除了行標籤)以數值變數的形式讀入,對應非數值變數則以因數的形式讀入,如例子中的 Cent.heat
項。在必要時可以改變變數類型。
函數 read.table()
可以用來直接讀入數據框
> HousePrice <- read.table("houses.data")
你常常需要忽略掉行標籤而直接使用默認的行標籤。這種情況下,輸入檔就如下面所示的一樣省略行標籤。
沒有行標籤的輸入檔格式: Price Floor Area Rooms Age Cent.heat 52.00 111.0 830 5 6.2 no 54.75 128.0 710 5 7.5 no 57.50 101.0 1000 5 4.2 no 57.50 131.0 690 6 8.8 no 59.75 93.0 900 5 1.9 yes ...
這時,資料框可用如下命令讀入
> HousePrice <- read.table("houses.data", header=TRUE)
其中 header=TRUE
選項指定第一行是標題行,並且因此省略文件中給定的行標籤。