本系列是一個新的系列,在此系列中,我將和大家共同學習R語言。由於我對R語言的了解也甚少,所以本系列更多以一個學習者的視角來完成。
參考教材:《R語言實戰》第二版(Robert I.Kabacoff),書中所提到的John Cook的優秀博文,關於代碼規范的《來自Google的R語言編碼風格指南》。
Part 1:基本數據類型
Unit 1:向量、矩陣與數組
向量:用於存儲數值型、字符型或邏輯型數據的一維數組,使用c()
創建。
- 單個向量中的數據必須擁有相同的類型或模式(數值、字符或邏輯)。
- 標量是只含一個元素的向量,R中不存在一般意義上的標量。
- 向量的方括號中可以放置一個整數向量作為索引。
- R語言中,向量的索引從1開始,負數索引不表示倒數,而表示補集。有關更多索引的知識點,參閱Five kinds of subscripts in R。
矩陣:每個元素都擁有相同的模式的二維數組,可通過matrix()
創建。
mymatrix <- matrix(vector, nrow, ncol, byrow, dimnames)
matrix()
的第一個參數是vector
,包含了矩陣的元素。nrow
、ncol
用來指定行數和列數。byrow=FALSE
指定矩陣的填充模式是按行還是按列,默認是按列的。dimnames
可以接受一個二元列表,dimnames[[1]]
是行名,dimnames[[2]]
是列名,都是字符型向量。- 對矩陣的索引中方括號包含逗號分割的兩個參數,
x[i, ]
表示第i
行,x[, j]
表示第j
列,x[i, j]
表示第i
行第j
列。逗號兩邊的參數可以用數值列表,來表示多行多列。
數組:與矩陣類似,但維數可以大於2,可通過array()
創建。
myarray <- array(vector, dimensions, dimnames)
dimensions
是一個數值向量,給出各個維度的最大下標。dimnames
是一個和dimensions
等長的字符型列表,給出各個維度的名字,每個列表元素是一個與dimensions
對應位置等長對應的字符串向量。
Unit 2:數據框、因子
數據框:可以包含不同模式的數據,是R中最常處理的數據類型,用data.frame()
創建。
mydata <- data.frame(col1, col2, col3, ...)
-
數據框中,每一個
col
是列向量,它們的數據類型相同。 -
每一列的名稱可以由函數
names()
指定,用法為names(mydata) <- ...
。 -
也可以在賦值時直接給列命名,如
mydata <- data.frame( C1 = col1, C2 = col2, C3 = col3 )
這里使用的是
=
而不是<-
。 -
數據框可以看成矩陣的推廣,但是矩陣索引逗號是必須的,數據框卻可以不加逗號,此時的數值索引代表列索引,如果要表示第
i
行,應該使用mydata[i, ]
。 -
用
$
符號可以用來訪問數據框中的某一列。
為了簡化代碼,可以使用attach()
、detach()
和with()
函數。
-
函數
attach()
將數據框添加到R的搜索路徑中,detach()
則將數據框從搜索路徑移除。 -
函數
with()
可以創建一個針對數據框的環境,用法是with(mydata, { print(summary(C1)) plot(C1, C4) })
-
使用
with()
函數時,賦值僅在with
環境中生效。如果要創建全局變量,則應使用特殊賦值符<<-
替代標准賦值符<-
。
實例標識符:實例標識符指的是數據庫中的主鍵,在R中,可以通過row.names()
函數來指定,也可以在創建數據框時直接用row.names
參數指定。
patientID <- c(1, 2, 3, 4)
age <- c(25, 34, 28, 52)
diabetes <- c("Type1", "Type2", "Type1", "Type2")
status <- c("Poor", "Improved", "Excellent", "Poor")
patientdata <- data.frame(patientID, age, diabetes, status)
row.names(patientdata) <- patientID
對於數據框,可以用str()
函數來顯示其結構,用summary()
函數來顯示其統計概要。
名義變量和有序變量在R中稱為因子,函數factor()
以一個整數向量的形式存儲類別值,整數的范圍是\([1, k]\),\(k\)是名義變量中唯一值的個數,同時由一個字符串組成的內部向量將映射到這些整數上。
如果有向量
diabetes <- c("Type1", "Type2", "Type1", "Type1")
,則以下語句:diabetes <- factor(diabetes)
可以將其儲存為
(1, 2, 1, 1)
,並在內部將其映射為1 = Type1
和2 = Type2
。
要表示有序型變量,需要將factor()
函數的order
屬性指明為TRUE
,並用levels
屬性指定其因子排序(如果不指定,則按照字典序排列,一般情況下這不好)。
數值型變量可以用levels
和labels
參數來編碼成因子。
如果有向量
sex <- c(1, 2, 1, 1)
,則以下語句:sex <- factor(sex, levels=c(1, 2), labels=c("Male", "Female"))
可以將其轉化為因子
c("Male, "Female", "Male", "Male")
,並且所有不是1, 2
的值將被轉化為缺失值。
Unit 3:列表
列表是一些對象的有序集合,且這些對象之間可以是毫不相關的,用list()
函數創建一個列表。
mylist1 <- list(object1, object2, ...)
mylist2 <- list(name1=object1, name2=object2, ...)
g <- "My First List"
h <- c(25, 26, 18, 39)
j <- matrix(1:10, nrow=5)
k <- c("one", "two", "three")
mylist3 <- list(title=g, ages=h, j, k)
- 列表的訪問用雙重方括號,其中可以是數字索引,也可以是字符串表示的名字(需引號)。
- 列表的訪問可以用
$
符號,這樣訪問變量名不需要用引號。 - 許多R函數的運行結果都以列表的形式返回。
Part 2:數據的輸入
參考鏈接:《R數據的導入和導出》。
R語言擁有內置的文本編輯器,這使得手動輸入數據十分方便。在R中,edit()
可以調用這個文本編輯器,並且在關閉文本編輯器后返回一個副本。
mydata <- data.frame(age=numeric(0), gender=character(0), weight=numeric(0))
mydata <- edit(mydata) # 彈出文本編輯器
fix(mydata) # 第二行的等價寫法
除此外,我們常常會遇到較大的數據集,需要導入。請不要小看數據集的導入,在實際操作中導入可能會出現許多問題。
Unit 1:導入帶分隔符的文本文件
這種文件類型主要指csv, tsv
等,使用的函數是read.table(file, options)
。這里file
是文件路徑,options
是可選擇的選項。
header
:文件是否在第一行包含了變量名,如果是,需要設置成TRUE
。sep
:分隔符,默認為sep=""
,包含了空字符(一個或多個空格,回車,制表符)。除此外,常用的制定值有sep=","
和sep="\t"
。row.names
:指定行標記符。col.names
:如果header=FALSE
,就可以用此參數指定一個包含變量名的字符向量。如果header=FALSE
且沒有指定col.names
,則會自動命名為V1, V2, ...
。na.strings
:用於表示缺失值的字符向量。如na.strings=c("?")
,就表示將讀取到的"?"
設置為NA
。colClasses
:可以為每一列指定數據類型,當讀取大型文本文件時,可以可觀提升處理速度。quote
:用於對有特殊字符的字符串划定界限的字符串,默認是單引號或雙引號。skip
:讀取數據前跳過的行的數目,適用於具有頭注釋的文本文件。stringsAsFactors
:標記字符向量是否需要轉化為因子,默認是TRUE
,除非被colClasses
所覆蓋。text
:一個指定文字進行處理的字符串,用來取代file
(幾乎不用,如果這樣做為什么不直接使用edit()
?)
比較常用的選項可能是skip
(先看看是否有頭注釋)、header
(再看看是否包含變量名)、sep
(選擇分界符,這要用文本編輯器觀察一下以免被Excel欺騙)、col.names
(是否需要自己指定變量名)、na.strings
(是否需要處理缺失值)、stringsAsFactor
(有時候不希望字符串被轉化)。
Unit 2:導入Excel數據
導入Excel數據最簡單的方式,是通過導出為CSV格式,再使用read.table()
函數讀取。也可以使用xlsx
包中提供的read.xlsx()
函數進行讀取。
library(xlsx)
mydata <- read.xlsx(file, n)
這里file
是工作路徑,n
是工作表的索引。除此外,read.xlsx
還具有如下常用的可選參數:
rowIndex
:一個可選的數值向量,指定需要讀取的行號。如果不指定此參數,且下面的startRow
和endRow
也不指定,則會讀取所有的行。startRow
:當rowIndex
缺省時生效,指定開始讀取的行號(單個數值),適用於含有頭注釋的xlsx
文件。endRow
:當rowIndex
缺省時生效,指定結束讀取的行號(單個數值)。colIndex
:一個可選的數值向量,指定需要讀取的列號。如果不指定此參數則讀取所有的列。header
:在需要讀取的行號中,是否將第一行作為變量名。colClasses
:與read.table()
函數中的一致。encoding
:如果表格中含有中文,則需要指定encoding='UTF-8'
。
尤其需要注意encoding
參數,對於我們需要讀取中文數據時十分有用。
Part 3:處理數據對象的函數
以下部分函數的實用性超乎我的想象,但是先前見到的R教程幾乎沒有提及。
length(object)
:顯示對象中元素的數量。dim(object)
:顯示某個對象的各維度長度,即各個維度的下標上限。向量的維度顯示為NULL
(應該使用length()
),數據框、矩陣、數組等維度將返回一個向量。str(object)
:顯示某個對象的結構。class(object)
:顯示某個對象的類或類型,如"numeric", "data.frame", "integer", "factor"
。mode(object)
:顯示某個對象的模式,如"numeric", "list"
。這不會給出data.frame, factor
之類的返回,實際上我也不能很好地區分class()
和mode()
。names(object)
:顯示對象中各成分的名稱。c(object, object, ...)
:將對象合並成一個向量。cbind(object, object, ...)
:按列合並對象,適用於合並數據框。rbind(object, object, ...)
:按行合並對象。object
:輸出某個對象。head(object)
:列出某個對象的開始部分,可類比Pandas庫。tail(object)
:列出某個對象的最后部分。ls()
顯示當前的對象列表。rm(object, object, ...)
:刪除對象。有一句常用的清除幾乎所有對象的語句是rm(list=ls())
。newobject <- edit(object)
:直觀地編輯對象,並另存為newobject
。如果沒有賦值,編輯將不會生效。fix(object)
:直接編輯對象,不需要賦值。