統計R語言實作筆記系列 – 資料尺度與變數類型

收集原始資料是統計的必要步驟,前一篇介紹過把資料輸入到 R 的方法,但是在收齊資料到執行統計分析之前,還有一些基本的要件必須定義清楚,例如資料的統計尺度為何,一般常見分為四種: 比例(ratio)、區間(interval)、順序(order)、類別(nominal),依據尺度不同,適用的統計模型也有所調整。

如果只用統計尺度對資料做定義,那麼計算程式經常會出現衝突,因為程式無法像人一樣辨別不同尺度的意義,因此需要按照機器能讀懂的方式給予變數一些規定,另一方面為了不使程式設計過於複雜,這些格式也要盡量能夠符合多變量數學運算的邏輯需求。

這些考量構成了 R 裡頭常見的變數類型:
1. 向量 vector()
2. 因素向量 factor()
3. 陣列 array()
4. 矩陣 matrix()
5. 資料框架 data.frame()

變數的基本單位: 向量Vector

所謂向量是一組觀察值的集合,僅有一個資料點可以視為向量的特例。大多時候,一個變數在程式中代表的意義就是一個向量。

向量的指定可以透過「 c() 」函數操作,例如:

x<-c(105,201,158,"嘗試")

x
[1] “105″  “201″  “158″  “嘗試"

一個向量中假如包含不同「格式」的資料,例如有數字也有文字,計算時就會出現錯誤訊息(此處以平均數計算為例):

mean(x)
[1] NA
警告訊息:
In mean.default(x) : argument is not
numeric or logical: returning NA

假如以資料表來看,下圖中的 a 、 b 變數各自都是一個向量。

r-data-向量-範例

向量之間是可以做加減乘除的,只要符合向量計算的數學規則就行。若非為了求值,也可以把向量結合成新的向量等等,端視運算需求,例如以下範例:

vector1<-c(10,15,16,18,19) vector2<-c(154,44,498,945) vector3<-vector1+vector2

vector3
[1]
10  15  16  18  19  154  44  498
945

此外也能透過向量的命名指令「 names() 」給予名稱。

names(vector1)<-c("yes1","yes2","yes3","yes4","yes5")

vector1
yes1 yes2 yes3 yes4 yes5

質化變數的專用向量: 因素向量 Factor

因素向量和一般向量的最大差異在於因素向量主要是用來存放分類變數,而非單純的數字,這部分的區別與資料尺度有關,指定一組資料集合為因素向量等於告訴 R ,該變數就是「順序」或者「分類」尺度。

常見的四種資料尺度雖然數學處理細節都有差異,但還是可以簡單劃分成「質變數(順序、類別)」與「量變數(區間、比例)」,質變數與量變數的運算差異很明顯(例如文字與數字),因此特別需要分別討論。

要把一個向量指定為「因素向量」,可以透過「 as.factor() 」指令來操作。

as.factor(vector3)
[1] 10
15  16  18
19  154  44  498  945
Levels: 10  15  16  18  19  44  154  498  945
# levels在此表示對變數vector3而言共有9種不同的分類

假如是順序變數,則可以利用「 ordered() 」配合「 levels=c() 」建立。

vector4<-c("First","Second","Third")

vector4order<-ordered(vector4,levels=c("Third","Second","First"))

vector4order
[1] First
Second Third
Levels: Third < Second < First
# 指定排序的levels時,從左至右的順序由小而大排列

機器特有的資料表達方式: 陣列 Array

陣列是記憶體儲存位置相鄰的一組資料,但計算方面的文字說明卻是個滿讓人迷惑的概念,既非座標向量卻又具有「維度」。

若把它類比成為數段向量組合成的加長版向量會比較容易理解,而其中每多一段向量都會增加一個維度。

建立陣列的指令是「 array() 」,基本語法如下:

array
function (data = NA, dim = length(data),
dimnames = NULL)

其中 dim 就是維度,下面的範例「 array1 」的意義便是「運用 1 到 30 的數字,建立一個 3 x 5 的 array (因此實際上這是個2維陣列,此時等於 3 x 5 的矩陣)」。

array1<-array(1:30, dim=c(3,5))

array1
[,1] [,2] [,3] [,4] [,5]
[1,]
1    4    7
10   13
[2,]
2    5    8
11   14
[3,]
3    6    9
12   15

下面的範例「 array2 」的意義則是「運用 1 到 30 的數字,建立 2 個 3 x 5 的 array 」。

array2<-array(1:30, dim=c(3,5,2))

array2
, , 1
[,1] [,2] [,3] [,4] [,5]
[1,]
1    4    7
10   13
[2,]
2    5    8
11   14
[3,]
3    6    9
12   15

, , 2
[,1] [,2] [,3] [,4] [,5]
[1,]
16   19   22
25   28
[2,]
17   20   23
26   29
[3,]
18   21   24
27   30

# 注意array資料排列的方式,是先從直行依序往下的

既然陣列可以類比成加長版的向量,那麼自然也就表示能把幾個單獨的向量結合成一個陣列了。陣列組成的方式有兩種,用「 rbind() 」指定直行結合或是用「 cbind() 」指定橫列結合。

a<-c(1,2,3,4,5,6,7,8,9) b<-c(11,12,13,14,15,16,17,18,19) #創造兩向量ab

ab<-rbind(a,b) ab [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] a 1    2    3 4    5    6 7    8    9 b 11   12   13 14   15   16 17   18   19 #橫列結合a,b成為陣列ab

ab<-cbind(a,b) ab a  b  [1,] 1 11  [2,] 2 12  [3,] 3 13  [4,] 4 14  [5,] 5 15  [6,] 6 16  [7,] 7 17  [8,] 8 18  [9,] 9 19 #直行結合a,b成為陣列ab

另外,陣列的命名可以透過「 dimnames(陣列)[[維度]] 」來給予,此函式透過實作畫面會比較容易理解。

array2
, , 1
   s1
s2 s3 s4 s4
s1
1  4  7 10 13
s2
2  5  8 11 14
s3
3  6  9 12 15

, , 2
   s1
s2 s3 s4 s4
s1 16 19 22 25 28
s2 17 20 23 26 29
s3 18 21 24 27 30
#原本array2的行列名稱是S+數字

c(“No.1″, “No.2″,
“No.3″)-dimnames(array2)[[1]]
# 由於原本array2的陣列內容是「3 x 5的矩陣2個」,因此第一維數字會應到三個列名稱。注意箭頭方向。

array2
, , 1
s1 s2 s3 s4 s4
No.1
1  4  7 10 13
No.2
2  5  8 11 14
No.3
3  6  9 12 15

, , 2
s1 s2 s3 s4 s4
No.1 16 19 22 25 28
No.2 17 20 23 26 29
No.3 18 21 24 27 30

c(“t1″, “t2″,"t3″, “t4″, “t5″)-dimnames(array2)[[2]]
array2
, , 1
t1 t2 t3 t4 t5
No.1
1  4  7 10 13
No.2
2  5  8 11 14
No.3
3  6  9 12 15

, , 2
t1 t2 t3 t4 t5
No.1 16 19 22 25 28
No.2 17 20 23 26 29
No.3 18 21 24 27 30
# 由於原本 array2 的陣列內容是「3 x 5的矩陣 2 個」,因此第二維數字會應到五個行名稱。注意箭頭方向。

c(“p1″,"p2″)-dimnames(array2)[[3]]
array2
, , p1
t1 t2 t3 t4 t5
No.1
1  4  7 10 13
No.2
2  5  8 11 14
No.3
3  6  9 12 15

, , p2
t1 t2 t3 t4 t5
No.1 16 19 22 25 28
No.2 17 20 23 26 29
No.3 18 21 24 27 30
# 由於原本 array2 的陣列內容是「 3 x 5 的矩陣 2 個」,因此第三維數字會應到 2 個矩陣的名稱。注意箭頭方向。

假如輸入「 array 的名稱[數字]」, R 會輸出該陣列中的第幾個元素。

array2[3]
[1] 3
array2[17]
[1] 17

「dim(陣列名稱)」則會顯示該陣列的維度資訊。

dim(array2)
[1] 3 5 2
#表示array2有三個維度,各維度分別為3,5,2

讓我們多試一點,一維的陣列等於向量、二維陣列等於矩陣、三維陣列等於兩個矩陣,那麼假如維度參數超過三個以上又會如何?

四維以上陣列的結果將以排列組合的方式列出。

array3<-array(1:30, dim=c(2,2,2,3))

array3
, , 1, 1
[,1] [,2]
[1,]
1    3
[2,]
2    4

, , 2, 1
[,1] [,2]
[1,]
5    7
[2,]
6    8

, , 1, 2
[,1] [,2]
[1,]
9   11
[2,]
10   12

, , 2, 2
[,1] [,2]
[1,]
13   15
[2,]
14   16

, , 1, 3
[,1] [,2]
[1,]
17   19
[2,]
18   20

, , 2, 3
[,1] [,2]
[1,]
21   23
[2,]
22   24

多變量運算的基本: 矩陣 Matrix

矩陣是基於線性代數的所有統計都必須的形式,前面的例子中顯示了,二維陣列等同一個矩陣。

R的矩陣語法如下:

matrix
function (data = NA, nrow = 1, ncol = 1,
byrow = FALSE, dimnames = NULL)

想建立一個矩陣,可以用「 as.matrix() 」指令,同時要記得設定行列數。以下的例子用了 1 到 9 的數字建立一個 3 x 3 的矩陣。

matrix1<-matrix(1:9, nrow=3,ncol=3)

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

如同向量一樣, R 中的矩陣也是可以直接執行四則運算的,不過「向量與矩陣」、「矩陣與矩陣」之間的乘法符號是「%*%」,比較特殊一點。

matrix2<-matrix(10:18, nrow=3,ncol=3)

matrix2
[,1] [,2] [,3]
[1,]
10   13   16
[2,]
11   14   17
[3,]
12   15   18
#建立一個矩陣matrix2

matrix1%*%matrix2
[,1] [,2] [,3]
[1,]
138  174  210
[2,]
171  216  261
[3,]
204  258  312
#矩陣1與矩陣2相乘的結果

從向量建立矩陣的方式與建立陣列十分類似,可選用函數「 rbind() 」或「 cbind() 」。

a<-c(3,5) b<-c(1,2) # 設立a,b兩向量

ab<-rbind(a,b)

ab
[,1] [,2]
a
3    5
b
1    2

ab2<-cbind(a,b) ab2 a b [1,] 3 1 [2,] 5 2

矩陣計算尚有一些內建的函數可使用,如轉置矩陣「 t() 」、輸出矩陣對角線值「 diag() 」、求解反矩陣「 solve() 」、計算特徵值與特徵向量「 eigen() 」。

t(ab2)
[1,] [2]
a  3 5
b  1
2

diag(matrix1)
[1] 1 5 9

eigen(matrix1)
$values
[1]
1.611684e+01 -1.116844e+00 -4.054214e-16

$vectors
[,1]       [,2]       [,3]
[1,] -0.4645473 -0.8829060  0.4082483
[2,] -0.5707955 -0.2395204 -0.8164966
[3,] -0.6770438  0.4038651
0.4082483

solve(ab2)
[,1] [,2]
a
2   -1
b
-5    3
# 注意反矩陣並非總是有解,數學說明可參考wiki

定義一組有意義的變數: 資料框架 Data Frame in R

資料框架主要是用來定義一個完整的資料範圍,在這個範圍下可能就保含了前述介紹的各種變數類型(多個向量、矩陣等)。一般利用「 read.table 」等指令輸入原始資料時,其實整個資料表格就是以 data.frame 的形式被保存。

不過設定 data frame 時要注意各行之間或各列之間的長度是否相等。

data<-data.frame(ab)

data
  X1
X2
a
3  5
b
1  2
# ab是前面建立的2×2矩陣

改變行列欄位名稱的方法也大同小異,可用「 names() 」、「 colnames() 」、「 rownames() 」等指令。

colnames(data)<-c("True","False")

data
True False
a
3     5
b
1     2

rownames(data)<-c("High","Low")

data
True False
High
3     5
Low
1     2

使用「 $ 」符號,如 A$B ,將可以指定 A 資料框架中的 B 向量,在原始資料表格很巨大時,這是一個相當好用的技巧。

selectx<-data$True selectx [1] 3 1

更多精彩內容,千萬別錯過:

* 統計R語言實作筆記系列 – 2D視覺化進階 GGPLOT()的基本架構(一)

* 統計R語言實作筆記系列 – 用 SHINY 套件極速打造你的商業智慧分析網站!

* 統計R語言實作筆記系列- 直線ABLINE()、曲線CURVE()與多邊形POLYGON()

* 統計R語言實作筆記系列 – 2D視覺化入門

* EXCEL 交互參照必學神器, 用 LOOKUP 系列函數一鍵搞定資料比對 : HLOOKUP篇

(Visited 2,665 times, 19 visits today)

Wendell.Huang

科技公司嫌棄太活潑,消費品牌挑剔太沉悶..., 經常必須解釋自己在學什麼, 不小心就摔破對方眼鏡的跨領域玩家。

One Comment

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *