本系列是一個新的系列,在此系列中,我將和大家共同學習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):直接編輯對象,不需要賦值。
