建立 .First 與 .Last 函數
最后更新于:2022-04-01 02:44:37
# 建立 .First 與 .Last 函數
R 可以利用 .First 與 .Last 函數,建立 R 環境 開始與結束時會自動執行的函數。
- 建立 .Rprofile 檔案
- 建立 .First 與.Last 函數
~~~
touch ~/.Rprofile
open -a Textedit ~/.Rprofile
~~~
.Rprofile 檔案內容
~~~
.First = function()
{
library(ggplot2) # 開啓 RStudio 時會自動載入ggplot2package
}
.Last = function()
{
}
~~~
註:以上是在 Mac 環境下操作,但不同環境應該大同小異。
定義函數
最后更新于:2022-04-01 02:44:34
# 定義函數
R 可以將常重複執行的程式碼定義成函數,如以下定義
~~~
函數名稱 <- function(參數){
程式重複執行的部份
}
> add <- function(a, b){
+ a + b
+ }
> add(1,3)
[1] 4 # R 預設最後一個運算式當作回傳的值
> add_special <- function(a, b){
+ c = a + b
+ return(0) # 可以自訂要回傳的部份
+ }
> add_special(1,3)
[1] 0
> add_default <- function(a = 1, b = 2){
# 可以自訂函數的預設值
+ a + b
+ }
> add_default() #沒給參數值
[1] 3
> add_default(2) # 給 a = 2,因為給定參數是依照參數順序,如果想給 b,但不想給定 a,可以利用以下方式
[1] 4
> add_default(b = 3)
[1] 4
~~~
Chapter 7 – 自訂函數
最后更新于:2022-04-01 02:44:32
# Chapter 7 - 自訂函數
1. 定義函數
1. 建立 .First 與 .Last 函數
資料合併與分割
最后更新于:2022-04-01 02:44:30
# 資料合併與分割
資料整理最後來介紹如何合併與分割資料。
- union、cbind 與 rbind 函數
- merge 函數
- split 函數
- subset 函數
### 資料合併
~~~
> x <- c(1, 2, 3)
> y <- c(10, 20, 30)
> union(x ,y) # union 如英文名稱就是取聯集。
[1] 1 2 3 10 20 30
> rbind(x, y) # 透過 row 合併。
[,1] [,2] [,3]
x 1 2 3
y 10 20 30
> cbind(x, y) # 透過 column 合併。
x y
[1,] 1 10
[2,] 2 20
[3,] 3 30
> x <- cbind(c("Tom", "Joe", "Vicky"), c(27, 29, 28))
> y <- cbind(c("Tom", "Joe", "Vicky"), c(178, 186, 168))
> colnames(x) <- c("name", "age")
> colnames(y) <- c("name", "tall")
> merge(x, y, by = "name") # 將 data.frame 透過一個欄位進行合併。
name age tall
1 Joe 29 186
2 Tom 27 178
3 Vicky 28 168
> x <- cbind(c("Tom", "Joe", "Vicky", "Bob"), c(27, 29, 28, 25))
> y <- cbind(c("Tom", "Joe", "Vicky", "Bruce"), c(178, 186, 168, 170))
> colnames(x) <- c("name", "age")
> colnames(y) <- c("name", "tall")
> merge(x, y, by = "name", all = T) # alt 是用來詢問是否顯示所有資料,像 Bob 與 Bruce 都有一欄資料沒有,所以沒下 all = T,應該不會出現 Bob 與 Bruce 資料。
name age tall
1 Bob 25 <NA>
2 Joe 29 186
3 Tom 27 178
4 Vicky 28 168
5 Bruce <NA> 170
> merge(x, y, by = "name", all.x = T) # 只顯示 x 有的資料,所以 Bruce 就不會出現。
name age tall
1 Bob 25 <NA>
2 Joe 29 186
3 Tom 27 178
4 Vicky 28 168
> merge(x, y, by = "name", all.y = T) # 只顯示 y 有的資料,所以 Bob 就不會出現。
name age tall
1 Joe 29 186
2 Tom 27 178
3 Vicky 28 168
4 Bruce <NA> 170
~~~
### 資料分割
~~~
> data <- iris
> split(data, sample(rep(1:2, 75))) # rep(1:2, 75) 產生 1,2 交錯的向量,但加了前面的 sample 則是隨機抽取,所以向量 1,2 會被打亂,split 會依照 sample(rep(1:2, 75)) 分組,都是 1 的會在同一組,都是 2 的也會在同一組。
> data <- iris
> subset(data, Sepal.Length > 5) # 只會出現 Sepal.Length > 5 的資料
> subset(data, Sepal.Length > 5,select = Sepal.Length) # 只會出現 Sepal.Length > 5 的資料且欄位只有 Sepal.Length,select 代表會出現的欄位。
> subset(data, Sepal.Length > 5,select = -Sepal.Length) # selct = 負的代表不要出現的欄位。
~~~
資料變形
最后更新于:2022-04-01 02:44:27
# 資料變形
在第三章常提到 as 開頭的函數,例如:as.vector、as.array、as.matric、as.data.frame 等,其實就是資料變形函數的一種,以下介紹其他常用到的資料變形函數。
- stack 與 unstack 函數
- reshape 函數
~~~
> data <- iris # 使用 R 內建的資料。
> stack_data <- stack(data) # stack 函數將各行資料排成一直行,unstack 則是還原成未 stack 之前形態。
> library("longitudinalData")
> data <- artificialJointLongData # 此種資料稱作為縱向資料(Longitudinal Data),通常是單一物體重複測量值所產生的資料,記錄方式可以用長型資料(long format)或寬型資料(wide format)。
> data_long = reshape(data, direction="long", varying = list(c("v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10"), c("w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10"), c("x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10")), v.names = c("v", "w", "x"), idvar = "id") # 利用 reshape 函數將資料從 wide 轉成 long
> data_wide = reshape(data_long, direction="wide",v.names = c("v", "w", "x"), idvar = "id") # 利用 reshape 函數將資料從 long 轉成 wide
~~~
解釋以上 reshape 函數一些參數的用意。
- direction:資料要轉成哪種類型,long 或 wide。
- varying:用於 wide 轉 long 時,哪些欄位要變成一個欄位的長期觀察資料,例如 v0 ~ v1 要變成 v,w0 ~ w10 變成 w,x0 ~ x10 變成 x。
- v.names:對於 wide 轉 long 時,當作是 long 資料的欄位,對於 long 轉 wide,哪些欄位要變成多個欄位觀察值。
- idvar:非重複性觀察資料,多半是可以分辨觀察物體的變數,,例如:id、名稱等。
重新編碼
最后更新于:2022-04-01 02:44:25
# 重新編碼
分析資料前常常需要再次整理資料,方便日後做分析,整理資料第一步往往是將資料的調整值經過一些調整,以下介紹幾種重新編碼的方法。
- 透過邏輯判斷式
- 利用 cut 函數
~~~
> data <- iris # 使用 R 內建的資料。
> data$Sepal.Length <- ifelse(data$Sepal.Length > 5, 1,2) # Sepal.Length 如果大於 5 會變成 1,不會就會變成 2
> data$Species <- ifelse(data$Species %in% c(setosa), "IsSetosa","Notsetosa") # %in% 代表有包含到的概念
> x <- c(1, 5, 12, 18, 19, 21, 25, 31)
> cut(x, c(0, 10, 20, 30, 40), c(5, 15, 25, 35)) # cut 函數是透過切割點,重新賦予資料新的數值,本範例的切割的範圍是 0 ~ 10、10 ~ 20、20 ~ 30、30 ~ 40,0 ~ 10 範圍的賦予新的值是 5。
[1] 5 5 15 15 15 25 25 35
Levels: 5 15 25 35
~~~
Chapter 6 – 資料整理
最后更新于:2022-04-01 02:44:23
# Chapter 6 - 資料整理
1. 重新編碼
1. 資料變形
1. 資料合併與分割
迴圈結構
最后更新于:2022-04-01 02:44:21
# 迴圈結構
### 常見的迴圈結構
以下介紹三種迴圈與兩種改變迴圈狀態的方法。
- for
- while
- repeat
- break
- next
~~~
> y <- 0
> for (x in c(1:10)) y <- x + y # 1 加到 10,迴圈就是重複執行相同動作,x 依序帶入 1 到 10,第一次帶入 1 時,y = 0,所以是 1 + 0 = 1,第二次帶入時,x = 1,y 已經變成 1,所以變成 1 + 1 = 2,後面一直延續到 x = 10 迴圈就會停止。
> y <- 0
> for (x in c(1:10)) {
+ y <- x + y
+ }
> x <- 1
> y <- 0
> while (x <= 10) { # while 只要符合判斷式,就會一直重複執行括號內程式碼,直到不符合為止。
+ y <- x + y
+ x <- x + 1 # 這行很重要,如果沒有這行,程式碼會一直執行不會停止,因為判斷式是 x 小於等於 10,x 初始值是 0,如果不對 x 做些動作,x 會一直小於等於 10,所以這邊加 1,是希望執行到 x = 11 時,迴圈就會停止。
+ }
> x <- 1
> y <- 0
repeat { # repeat 與 while 有點類似,只是判斷式的部份,可以比較自由寫在括號內任一地方,且跳出迴圈是利用 break 方式。
> repeat {
+ if (x > 10) break # break 是會執行跳出迴圈的動作,
意味程式停止。
+
+ y <- x + y
+ x <- x + 1
+ }
> x <- 1
> y <- 0
> repeat {
+ if (x > 10) { # 此部份判斷式多了一個 x = 5 部份
+ break
+ } else if (x == 5) {
+ x <- x + 1
+ next # next 是指跳過此次的迴圈,執行下一次的迴圈,所以這邊會被跳過 x = 5,代表 5 不會被加到,那有人有疑惑那為何上面要有一個 x <- x + 1,因為跳過 x 還是需要執行加 1 的動作,不然程式只會到 5 不會到 6,想要測試此狀況,就把 x <- x + 1 改成 print(x),就會發現程式一直跑停不下來。
+ }
+
+ y <- x + y
+ x <- x + 1
+ }
~~~
條件執行
最后更新于:2022-04-01 02:44:18
# 條件執行
### 常見的條件執行
以下介紹三種常見的條件執行。
- if else
- if else if else
- switch
~~~
# if A 判斷式
# A 判斷式為 True,會執行此區段程式碼。
# else
# A 判斷式為 False,會執行此區段程式碼。
> x <- 1
> if (x > 0) {
+ y <- 5
+ } else {
+ y <- 10
+ }
> if (x > 0) y <- 5 else y <- 10 # 單行的寫法。
> y
[1] 5
> y <- ifelse(x > 0, 5, 10) # 利用 ifelse(判斷式, True 給 5, False 給 10)。
> y
[1] 5
# if A 判斷式
# A 判斷式為 True,會執行此區段程式碼。
# else if B 判斷式
# B 判斷式為 True,會執行此區段程式碼。
# else
# A 與 B 判斷式都是 False,會執行此區段程式碼。
+ y <- 5
+ } else if (x > 2) {
+ y <- 10
+ } else {
+ y <- 3
+ }
> y
[1] 3
# switch(回傳數值代表執行第幾個程式片段, 程式片段 1, ..., 程式片段 N)
# switch(回傳名稱代表執行哪個名稱的程式片段, 程式名稱 A 片段, ..., 程式名稱 N 片段)
> switch(3, 10, 3 + 5, 3 / 3)
[1] 1
> switch(1, 10, 3 + 5, 3 / 3)
[1] 10
> switch(2, 10, 3 + 5, 3 / 3)
[1] 8
> switch("first", first = 1 + 1, second = 1 + 2, third = 1 + 3)
[1] 2
> switch("second", first = 1 + 1, second = 1 + 2, third = 1 + 3)
[1] 3
> switch("third", first = 1 + 1, second = 1 + 2, third = 1 + 3)
[1] 4
~~~
邏輯判斷式
最后更新于:2022-04-01 02:44:16
# 邏輯判斷式
### 常見的邏輯判斷符號
以下介紹常見的邏輯判斷的符號。
- <、>:小於、大於。
- <=、>=:小於等於、大於等於。
- ==、!=:等於、不等於。
- A %in% B:A 是否在 B 中。
- &&、&:交集,& 適用於向量式的邏輯判斷,&& 適用於單一值的邏輯判斷。
- ||、|:聯集,| 適用狀況與 & 相同,|| 適用狀況與 && 相同。
~~~
> x <- 5
> y <- 10
> x > 3
[1] TRUE
> x >= 6
[1] FALSE
> x <= 6
[1] TRUE
> x < 3
[1] FALSE
> !(x > 3) # 前面多加一個有否定功能,所以 True 變成 False,如果是 False 則變成 True。
[1] FALSE
> x %in% c(1:6)
[1] TRUE
> x > 4 || y > 10
[1] TRUE
> x > 4 && y > 10
[1] FALSE
> z = c(1,2,3)
> z > 0 & z > -1
[1] TRUE TRUE TRUE
> z > 0 && z > -1 # && 只可以比較單一值,所以只有抓 z 的第一元素跟 0 與 -1 比較。
[1] TRUE
~~~
Chapter 5 – 流程控制
最后更新于:2022-04-01 02:44:14
# Chapter 5 - 流程控制
1. 邏輯判斷式
1. 條件執行
1. 迴圈結構
讀取資料庫的資料
最后更新于:2022-04-01 02:44:12
# 讀取資料庫的資料
### 讀取資料庫的資料
利用 DBI、gWidgets、RMySQL 與 dbConnect 等 package 讀取資料庫資料,以下是讀取 MySQL 資料庫當作範例。
~~~
> library(DBI) # DBI 是 R Database Interface
> library(gWidgets)
> library(RMySQL) # MySQL 在 R 的 INterface
> library(dbConnect)
> con <- dbConnect(MySQL(), dbname = "house_development", username="root", password="123456") # 建立資料庫連線
>
> dbSendQuery(con,"SET NAMES utf8") #需設定 UTF-8,不然中文會亂碼。
<MySQLResult:(94576,0,0)>
> dbClearResult(dbListResults(con)[[1]])
[1] TRUE
>
> dbGetQuery(con,"show variables like 'character_set_%'") # 查詢資料庫基本設定
Variable_name Value
character_set_client utf8
character_set_connection utf8
character_set_database utf8
character_set_filesystem binary
character_set_results utf8
character_set_server utf8
character_set_system utf8
character_sets_dir /usr/local/Cellar/mysql/5.6.12/share/mysql/charsets/
data = dbGetQuery(con, "select * from raws") # 使用 SQL query 讀取資料。
~~~
註:如果資料庫不太熟,卻又想學習基本的語法的話,推薦 [新SQL 基礎講座 <增訂第二版>](http://www.books.com.tw/products/0010396522),此本的好處是記載不同資料庫的語法且淺顯易懂。
輸出資料
最后更新于:2022-04-01 02:44:09
# 輸出資料
### 透過 write.table 輸出資料
以下利用 write.table 輸出 CSV 檔案。
~~~
data <- iris # iris 是 R 內建的資料。
write.table(data, file = "test.CSV", sep = ",")
~~~
### 輸出 XML 檔案
跟輸入 XML 檔案一樣,是使用 XML package 來實做,但會需要利用到建立 tag 的函數。
~~~
> data <- iris
> xml <- xmlTree()
> xml$addTag("document", close = FALSE) # 建立一個名為 document 的 tag。
> for (i in 1:nrow(data)) {
+ xml$addTag("row", close = FALSE) # 建立一個名為 row 的 tag。
+ for (j in names(data)) {
+ xml$addTag(j, data[i, j]) # j 為欄位名稱,所以是依序建立不同欄為名稱的 tag, 並賦予值與結束此 tag。
+ }
+ xml$closeTag() # 建立 tag 時,如果有下參數 close = FALSE 的話,記得要在結束 tag 地方下 closeTag()。
+ }
> xml$closeTag()
> saveXML(xml, "test.xml")
[1] "test.xml"
~~~
XML 檔案輸出結果。
~~~
<?xml version="1.0" encoding="UTF-8"?>
<document>
<row>
<Sepal.Length>5.1</Sepal.Length>
<Sepal.Width>3.5</Sepal.Width>
<Petal.Length>1.4</Petal.Length>
<Petal.Width>0.2</Petal.Width>
<Species>setosa</Species>
</row>
.
.
.
.
</document>
~~~
### 輸出 RDA 檔案
利用 save 函數輸出 RDA 檔案。
~~~
> data <- iris
> save(data, file="test.rda")
~~~
匯入資料
最后更新于:2022-04-01 02:44:07
# 匯入資料
### 透過 read.table 匯入資料。
read.table 可以讀取大多數的 ASCII 資料,以下先以 CSV 檔為代表,因為是目前最普遍見到的匯入資料格式。
~~~
> data <- read.table("Desktop/data.csv", header = TRUE, sep = ",") # 檔案路徑是相對於目前的工作目錄,header 是指資料是否有包含欄位名稱,sep 是指資料的分隔符號。
> data <- read.table("Desktop/data.csv", header = TRUE, sep = ",", col.names = c("時間", "新聞標題")) # col.names 設定 column 欄位名稱。
> data <- read.table("Desktop/data.csv", header = FALSE, sep = ",", skip = 10) # skip 是指跳過前 X 筆資料,這個部份要注意,要跳過資料,column 欄位就不可以出現在資料裡,因為它也被算在要 skip 部份。
> data <- read.table("Desktop/data.csv", header = TUE, sep = ",", encoding = "UTF-8") # encoding 是指定檔案的文字編碼
> data <- read.table("Desktop/data.csv", header = TRUE, sep = ",", na.strings = NA) # na.strings 指定發生 NA 要用什麼符號代替。
~~~
### 文字編碼問題
匯入 CSV 檔的時候會碰到一種比較特別的問題,就是作業系統編碼不同的問題,Windows 的中文編碼是 big5,而 Linux / Mac 都是 UTF-8,所以在 Linux / Mac 匯入來自於 Windows CSV 檔常常會發生亂碼,那該如何解決此問題,本人的做法是將資料讀進來轉成 UTF-8,在輸出一份 CSV 檔,以下先以一個 CSV 檔為主,加以調整修改就可以改成一次跑一個資料夾下的所有 CSV 檔。
~~~
> data <- readLines("Desktop/A_lvr_land_A.CSV", encoding="big5") # 讀取實價登入資料,是一行一行讀取進來。
> data <- iconv(data, "big5", "utf8") 將資料轉成 UTF-8。
> column_count <- length(strsplit(data[1], ",")[[1]])
row_count <- length(data) # 計算 column 與 count 個數。
> fix_data <- matrix(NA, nrow = row_count, ncol = column_count) # 建立一個空的 NA 矩陣,維度來自於 row_count 與 column_count。
> for(row in 1:row_count) {
+ for(col in 1:column_count) {
+ fix_data[row,col] <- strsplit(data[row], ",")[[1]][col] # 執行 for loop 將資料塞入 fix_data。
+ }
+ }
> write.table(fix_data[2:row_count,], file = "fix_A_lvr_land_A.CSV", sep = ",", col.names = fix_data[1,]) # 將資料輸出,輸出注意一點,因為第一 row 是欄位名稱,所以記得指標要從 2 開始,指標 1 的部分要放到 col.names。
~~~
### 讀取 XML 檔案。
這邊順便也介紹讀取 XML 方法,是因為讀取 XML 檔案比較不會發生上述的編碼問題,所以如果兩者都會的話,以後有提供 CSV 與 XML 檔案時,就可以選 XML 檔案以免製造自己的麻煩。
~~~
> library(XML) # 要先安裝 XML package 再載入。
> data <- xmlToDataFrame("Desktop/A_lvr_land_A.XML")
~~~
### 匯入 RDA 檔案
匯入 RDA 檔案有以下兩種方式。
- 在工作目錄直接點選 RDA 檔案,選擇匯入即可。
- 在 console 下 load(檔案名稱)。
Chapter 4 – 資料匯入與輸出
最后更新于:2022-04-01 02:44:05
# Chapter 4 - 資料匯入與輸出
1. 匯入資料
1. 輸出資料
1. 讀取資料庫的資料
資料框架
最后更新于:2022-04-01 02:44:02
# 資料框架
### 利用 data.frame 建立資料框架
資料框架類似資料表,常當作大量資料集,例如:匯入外部檔或讀取資料庫資料等。
~~~
> name <- c("Joe", "Bob", "Vicky")
> age <- c("28", "26", "34")
> gender <- c("Male","Male","Female")
> data <- data.frame(name, age, gender)
> View(data) # 自動點選 data 變數就會開啟資料的畫面。
~~~
### 透過指標與名稱提取資料
資料框架的提取資料方法跟矩陣或陣列的都很類似。
~~~
> data
n a g
r1 Joe 28 Male
r2 Bob 26 Male
r3 Vicky 34 Female
> data[1,]
name age gender
1 Joe 28 Male
> data[,1]
[1] Joe Bob Vicky
Levels: Bob Joe Vicky
> data[1, 1]
[1] Joe
Levels: Bob Joe Vicky
> data[,"name"]
[1] Joe Bob Vicky
Levels: Bob Joe Vicky
> data[1:2,"name"]
[1] Joe Bob
Levels: Bob Joe Vicky
> data$name[1:2]
[1] Joe Bob
Levels: Bob Joe Vicky
~~~
### 基本相關函數
- header:取得資料框架前六比資料(預設是 6)。
- names:修改或查詢 column 名稱。
- colnames:設定 column 名稱。
- row.names:修改或查詢 row 名稱。
- rownames:設定 row 的名稱
- summary:顯示資料基本資訊。
~~~
> data
n a g
r1 Joe 28 Male
r2 Bob 26 Male
r3 Vicky 34 Female
> head(data) # 因為筆數不夠多,所以全部都顯示。
n a g
r1 Joe 28 Male
r2 Bob 26 Male
r3 Vicky 34 Female
> head(data, 1L) # 只顯示第一筆資料。
n a g
r1 Joe 28 Male
> names(data)
[1] "name" "age" "gender"
> names(data) <- c("n", "a", "g")
> names(data)
[1] "n" "a" "g""
> colnames(data)
[1] "n" "a" "g"
> row.names(data)
[1] "1" "2" "3"
> row.names(data) <- c("r1", "r2", "r3")
> row.names(data)
[1] "r1" "r2" "r3"
> rownames(data)
[1] "r1" "r2" "r3"
> summary(data)
name age gender
Bob :1 26:1 Female:1
Joe :1 28:1 Male :2
Vicky:1 34:1
~~~
列表
最后更新于:2022-04-01 02:44:00
# 列表
### 利用 list 建立列表
列表跟向量很相似,但最大的不同在於列表可以包含不同資料屬性的資料。
~~~
> x <- list(a = 1, b = TRUE, c = "test", d = c(1, 2, 3))
> x
$a
[1] 1
$b
[1] TRUE
$c
[1] "test"
$d
[1] 1 2 3
~~~
### 透過指標與名稱提取資料
~~~
> x <- list(a = 1, b = TRUE, c = "test", d = c(1, 2, 3))
> x[1]
$a
[1] 1
> x[[1]]
[1] 1
> x$b # 是利用 % 加上名稱提取資料
[1] TRUE
> x[[4]][1] # x[[4]] 取出第四個值,因為第四個值是向量,所以可以在取一次指標,取出向量的元素值。
[1] 1
~~~
### 基本相關函數
- as.list:建立列表
- is.list:判斷是否為列表
- attributes:查看所有元素的名稱,names 也有相同功能。
~~~
> x <- list(a = 1, b = TRUE, c = "test", d = c(1, 2, 3))
> as.list(c(1,2,3))
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
[1] 3
> is.list(x)
[1] TRUE
> attributes(x)
$names
[1] "a" "b" "c" "d"
> names(x)
[1] "a" "b" "c" "d"
~~~
因子
最后更新于:2022-04-01 02:43:58
### 因子
### 利用 factor 建立因子
因子有點像經過分級之後的向量,因子大多可以用在統計上的迴歸分西與實際設計等。
~~~
> x <- c(1, 2, 4, 3, 1, 2, 3, 4,1)
> factor(x)
[1] 1 2 4 3 1 2 3 4 1
Levels: 1 2 3 4
> factor(x, labels = c("一", "二", "三", "四")) # 可自訂 Level 的名稱。
[1] 一 二 四 三 一 二 三 四 一
Levels: 一 二 三 四
> factor(x, ordered = TRUE) # ordered 代表可做排序
[1] 1 2 4 3 1 2 3 4 1
Levels: 1 < 2 < 3 < 4
> factor(c(1, 2, 1, NA, 2), exclude = NA) # 可利用 exclude 排除特定資料。
[1] 1 2 1 <NA> 2
Levels: 1 2
> factor(c(1, 2, 1, NA, 2), exclude = 2)
[1] 1 <NA> 1 <NA> <NA>
Levels: 1 <NA>
> factor(c(1, 2, 1, NA, 2), exclude = NULL) # 不排除任何資料。
[1] 1 2 1 <NA> 2
~~~
### 透過指標提取資料
~~~
> x[1] # [] 與 [[]] 結果一致,因為因子只有值沒有其他相關資料。
[1] 1
> x[[1]]
[1] 1
> x[1:2] # 指標可以使用向量。
[1] 1 2
> x[c(1, 3, 5)]
[1] 1 4 1
~~~
### 基本相關函數
- is.factor:判斷是否為因子。
- as.factor:將變數轉為因子。
- is.ordered:判斷是否為排序過的因子。
- as.ordered:將因子排序。
- which:找出符合條件的指標。
~~~
> x <- c(1, 2, 4, 3, 1, 2, 3, 4,1)
> as.factor(x)
[1] 1 2 4 3 1 2 3 4 1
Levels: 1 2 3 4
> is.factor(x)
[1] FALSE
> is.factor(as.factor(x))
[1] TRUE
> is.ordered(factor(x, ordered = TRUE))
[1] TRUE
> is.ordered(factor(x, ordered = FALSE))
[1] FALSE
> as.ordered(factor(x))
[1] 1 2 4 3 1 2 3 4 1
Levels: 1 < 2 < 3 < 4
> which(x == 1) # 找出 x 等於 1 的指標
[1] 1 5 9
~~~
矩陣
最后更新于:2022-04-01 02:43:55
# 矩陣
### 利用 matrix 建立矩陣
當陣列是 2 維的狀況就是所謂的矩陣,可以利用 matix 產生矩陣,也可以用之前產生陣列的方法實作。
~~~
> matrix(c(1:4), nrow = 2, ncol = 2) # 預設是按照 column 填入資料
[,1] [,2]
[1,] 1 3
[2,] 2 4
> matrix(c(1:4), nrow = 2, ncol = 2, byrow = TRUE) # 可以更改成按照 row 填入資料
[,1] [,2]
[1,] 1 2
[2,] 3 4
~~~
### 透過指標提取資料
矩陣跟陣列一樣,還是可以透過指標選取矩陣的部份元素。
~~~
> x <- c(1, 2, 3)
> y <- c(4, 5, 6)
> z = rbind(x, y)
> z
[,1] [,2] [,3]
x 1 2 3
y 4 5 6
> z[,1] # 選取第一行(column、直)
x y
1 4
> z[1,] # 選取第一列(row、橫)
[1] 1 2 3
> z[1,1:2] # 選取第一列第一到二行
[1] 1 2
~~~
### 基本相關函數
- t(x):將矩陣轉置。
- %*%:矩陣相乘。
- diag:產生一個對角矩陣,或回傳矩陣的對角線向量
- det:計算矩陣行列式值,一定是要對稱矩陣。
- solve:傳回矩陣的反矩陣,非常適合解線性方程式。
- eigen:計算矩陣的特徵向量與特徵值。
- rownames:修改或查詢 row 名稱。
- colnames:修改或查詢 column 名稱。
~~~
> x <- c(1, 2, 3)
> y <- c(4, 5, 6)
> z <- rbind(x, y)
[,1] [,2] [,3]
x 1 2 3
y 4 5 6
> t(z)
x y
[1,] 1 4
[2,] 2 5
[3,] 3 6
> z %*% z # 矩陣相乘要符合前者 column 維度 = 後者 row 維度,如果沒有會發生錯誤!
錯誤在z %*% z : 非調和引數
> v <- z %*% t(z)
x y
x 14 32
y 32 77
> w <- diag(c(1,2,3)) # 傳入向量回傳一個對角矩陣
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 2 0
[3,] 0 0 3
> diag(w) # 傳入矩陣回傳矩陣對角線向量
[1] 1 2 3
> det(v) #一定要對稱矩陣才可以計算。
[1] 54
> solve(v)
x y
x 1.4259259 -0.5925926
y -0.5925926 0.2592593
> b = c(1,1) 解 Ax = b,求出 x 向量 A:變數 v,b:變數 b
> solve(v,b)
x y
0.8333333 -0.3333333
> u = matrix(1:9, nrow = 3, ncol = 3)
> u
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
> eigen(u) # 特徵值
$values
[1] 1.611684e+01 -1.116844e+00 -5.700691e-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
> rownames(z) # 還沒修改的時候,是 x 與 y,因為當初是利用兩個向量,利用 rbind 組成,所以會利用向量的變數稱名當作 row 名稱。
[1] "x" "y"
> rownames(z) <- c("第一行", "第二行")
> rownames(z)
[1] "第一行" "第二行"
> colnames(z)
NULL
> colnames(z) <- c("第一列", "第二列", "第三列")
> colnames(z)
[1] "第一列" "第二列" "第三列"
> z
第一列 第二列 第三列
第一行 1 2 3
第二行 4 5 6
~~~
陣列
最后更新于:2022-04-01 02:43:53
# 陣列
### 利用 rbind、cbind 與 array 函數建立陣列
陣列可視為多維度的向量變數,跟向量一樣,所有陣列元素的資料屬性必須一致。
~~~
> x <- c(1, 2, 3)
> y <- c(4, 5, 6)
> rbind(x, y) # rbind 是利用 row(橫) 合併。
[,1] [,2] [,3]
x 1 2 3
y 4 5 6
> cbind(x, y) # cbind 是利用 column(直) 合併。
x y
[1,] 1 4
[2,] 2 5
[3,] 3 6
> array(x,c(1,3)) # c(1,3) 代表產生 1 x 3 陣列
[,1] [,2] [,3]
[1,] 1 2 3
> array(x,c(2,3)) # c(2,3) 代表產生 2 x 3 陣列
[,1] [,2] [,3]
[1,] 1 3 2
[2,] 2 1 3
> array(x,c(3,3)) # c(3,3) 代表產生 3 x 3 陣列
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 2 2
[3,] 3 3 3
~~~
### 透過指標提取資料
陣列與向量相同,可以透過指標或名稱選取陣列的元素。
~~~
> x <- c(1, 2, 3)
> y <- c(4, 5, 6)
> z = rbind(x, y)
> z
[,1] [,2] [,3]
x 1 2 3
y 4 5 6
> z[,1] # 選取第一行(column、直)
x y
1 4
> z[1,] # 選取第一列(row、橫)
[1] 1 2 3
> z[1,1:2] # 選取第一列第一到二行
[1] 1 2
~~~
### 基本相關函數
- 陣列加減乘除
- length:計算陣列中的所有元素個數。
- dim:列出維度資訊
- ncol、nrow:計算(column、直) 或 (row、橫) 個數。
- aperm:將陣列轉置
~~~
> x <- c(1, 2, 3)
> y <- c(4, 5, 6)
> z = rbind(x, y)
> z
[,1] [,2] [,3]
x 1 2 3
y 4 5 6
> z + z
[,1] [,2] [,3]
x 2 4 6
y 8 10 12
> z - 2*z
[,1] [,2] [,3]
x -1 -2 -3
y -4 -5 -6
> z * z # 相對應的陣列元素相乘
[,1] [,2] [,3]
x 1 4 9
y 16 25 36
> z / z # 相對應的陣列元素相除
[,1] [,2] [,3]
x 1 1 1
y 1 1 1
> length(z)
[1] 6
> dim(z) # 前者是 row,後者是 column。
[1] 2 3
> ncol(z)
[1] 3
> nrow(z)
[1] 2
> aperm(z) # 等同是從 rbind 轉成 cbind
x y
[1,] 1 4
[2,] 2 5
[3,] 3 6
~~~