R Essential

| 振导社会  | 程序设计  R 

入门

命令 功能 例子
?"*" 查看*的帮组文档 ?"data.frame"
??"*" 在帮助文档中搜索* ??"network"
ls() 查看可用对象  
rm() 移除对象 rm(list = ls())
删除当前环境中所有对象
getwd() 查看工作目录  
setwd(dir) 设置工作目录  
.packages(all.available=T) 查看安装了哪些包  
.libPaths() 查看包安装的路径  

OSX删除R:

# 查看安装了那些pkg
$ pkgutil --pkgs | grep r-project

# 删除
$ rm -rf /Library/Frameworks/R.framework /Applications/R.app \
   /usr/bin/R /usr/bin/Rscript

在.bash_profile文件中添加包安装路径:

export R_LIBS="~/Library/R/3.1/library":$R_LIBS
export R_LIBS="~/Library/R/3.2/library":$R_LIBS

添加包的多个路径时,RStudio中在~/.Rprofile文件中设置才有效:

.libPaths(c(.libPaths(), "/abspath/R/3.1/library"))

R 控制台安装源代码包:

install.packages('~/Downloads/RGtk2_2.20.31.tar.gz', repos = NULL, type="source")

或者在Shell命令行:

r CMD INSTALL RGtk2_2.20.31.tar.gz

从源代码安装包时,编译器的配置文件位于

/Library/Frameworks/R.framework/Resources/etc/Makeconf

也可在如下用户配置文件修改

~/.R/Makevars

解决ld: library not found for -lintl

# 1. 安装 gettext:
$ brew install gettext
# 2. 在 ~/.R/Makevars 文件中添加库路径:
PKG_LIBS=-L/usr/local/opt/gettext/lib

查看数据内部存储:

x <- 1 : 10
.Internal(inspect(x))
# @10611f800 14 REALSXP g0c5 [NAM(2)] (len=10, tl=0) 1,2,3,4,55,...

安装其它非CRAN源的包:

source("http://bioconductor.org/biocLite.R")
biocLite("RBGL")

基本类型

R不能直接存取内存,通过称之为对象(object)的特殊数据结构存取内存。这些对象通过符号(symbol)或变量(variable)访问,符号本身也是对象。R的typeof函数返回对象的类型1R的对象类型包括NULLclosureintegercomplex等。

mode函数返回对象的模式(mode),主要是为了和S语言的其它实现兼容。storage.mode函数返回参数的存储模式(storage mode),通常用于调用C或FORTRAN时,确定数据类型。在S语言中,整数和实数向量都是numeric模式,但存储模式不同。

基本类型

向量(vector)是最基本数据结构,R包含6种基本的原子向量(atomic vector):

typeof mode storage.mode
logical logical logical
integer numeric integer
double numeric double
complex complex complex
character character character
raw raw raw

单个数和字符串也是长度为1的向量,例如4.2和“four point two”。原子向量中的每个元素类型必须相同。向量的长度可为0。

列表(list)称为通用向量(generic vector),每个元素可以是不同数据类型。虽然列表也是向量,但通常说的向量是不包括列表的原子向量。

R语言由3种不同类型的对象构成,它们是calls、expressions和names,这些对象的模式分别为callexpressionname,可通过as.listas.call在列表和语言对象之间转换。符号(symbol)指向R的对象,R对象的名字通常是一个符号。符号能够通过函数as.namequote创建。符号的模式为name,存储模式和类型都为symbol,可通过as.characteras.name与字符串转换。

R的expression对象包含一个或多个语句(statement)。R的expression对象只有在显示调用eval时才被执行。expression对象与列表相似,访问元素的方法与列表一样。

函数对象包含三个元素:参数列表、函数体和环境。参数列表用逗号分割,可包含任意个数的参数。函数体通常是包含在大括号中的R语句。环境在函数创建时激活。这三部分可通过函数formalsbodyenvironment操作。as.listas.function函数可进行列表和函数的转换。

NULL是特殊的对象,与长度为0的向量不同,R中只有唯一的NULL对象。

对象属性

除NULL外的所有对象都可包含一个或多个属性。属性以成对列表(pairlist)方式存储,所有元素都有名字。通过attributes查看属性列表,通过attr获取单个属性。一些特殊的属性有特定的存取函数,例如因子的levels函数,数组的dimdimnames函数。属性被用于实现R的类结构。If an object has a class attribute then that attribute will be examined during evaluation.

数据结构

R的数据结构包括数组(array)和列表(list)。数组的所有元素类型必须一致,列表元素的类型可以不同。向量(vector)是一维数组,矩阵(matrix)是二维数组。数据框(data frame)是特殊的列表。

因子(factor)是特殊属性的向量,因子中每个元素唯一,每个元素称为因子的一个水平(level)。

创建及操作数据结构

向量

# 创建
> v <- c(10, 20, 30)
> names(v) <- c("Moe", "Larry", "Curly") 
> print(v)
Moe Larry Curly 
 10    20    30

> v["Larry"] 
Larry
20

# 追加
> v <- c(v, 4)
> w <- c(5,6,7,8)
> v <- c(v, w)

> v <- c(1,2,3)
> v[10] <- 10
> v # R extends the vector automatically
[1] 1 2 3 NA NA NA NA NA NA 10

> append(1:10, 99, after=5)
[1] 1 2 3 4 5 99 6 7 8 9 10

实验表明,通过append函数增加元素要比向量构造和赋值方法慢很多[1, P. 102]

矩阵

> A <- 1:6
> dim(A) <- c(2,3) 
> print(A)
    [,1] [,2] [,3] 
[1,]   1    3    5 
[2,]   2    4    6

> theData <- c(1.1, 1.2, 2.1, 2.2, 3.1, 3.2) 
> mat <- matrix(theData, 2, 3)
> mat
    [,1] [,2] [,3] 
[1,] 1.1  2.1  3.1 
[2,] 1.2  2.2  3.2

可以对矩阵的行列命名:

> rownames(mat) <- c("rowname1", "rowname2", ..., "rownamem") 
> colnames(mat) <- c("colname1", "colname2", ..., "colnamen")

因子

> f <- factor(v) # v is a vector of strings or integers
> f <- factor(v, levels) # If your vector contains only a subset of possible values ...

> f <- factor(c("Win","Win","Lose","Tie","Win","Lose")) 
> f
[1] Win Win Lose Tie Win Lose
Levels: Lose Tie Win

列表

# 1
> lst <- list(3.14, "Moe", c(1,1,2,3), mean) 
> lst
[[1]]
[1] 3.14

[[2]]
[1] "Moe"

[[3]]
[1] 1 1 2 3

[[4]]
function (x, ...) 
UseMethod("mean") 
<environment: namespace:base>

# 2
> lst <- list()
> lst[[1]] <- 3.14
> lst[[2]] <- "Moe"
> lst[[3]] <- c(1,1,2,3) 
> lst[[4]] <- mean

# 3
> lst <- list(mid=0.5, right=0.841, far.right=0.977) 
> lst
$mid
[1] 0.5

$right 
[1] 0.841

$far.right 
[1] 0.977

数据框

# 1
> dfrm <- data.frame(v1, v2, v3, f1, f2)

# 2
> dfrm <- as.data.frame(list.of.vectors)

# 3
> dfrm <- data.frame(p1=pred1, p2=pred2, p3=pred3, r=resp)

# 4
# 对大规模数据,提前分配内存,通过预分配的方式创建
> N <- 1000000
> dfrm <- data.frame(dosage=numeric(N), lab=character(N), response=numeric(N))
> dfrm <- data.frame(dosage=numeric(N), lab=factor(N, levels=c("NJ", "IL", "CA")), response=numeric(N))

增加“空列”:

> dfrm$abc <- ""
> dfrm$def <- 0

字符串不自动变为因子类型:

> N <- 100
> dfrm <- data.frame(dosage=numeric(N), lab=character(N), stringsAsFactors=FALSE)

索引方法

数据的索引(indexing)有[][[]]$三种方法,形如x[i]x[i, j]x[[i]]x[[i, j]]x$ax$”a”数据的索引从1开始,索引前加负号-表示删除这些索引的元素。

  • 对向量和矩阵,[[]]会抛弃所有namesdimnames属性,[]则不会;
  • 对列表,[]返回列表,[[]]返回列表的元素;
  • [[]]只能对单个元素索引,[]可以通过向量索引多个元素;
  • $只能用于列表索引,索引参数不能被计算(如果索引参数需要计算,采用x[[expr]]),索引的对象不存在时返回NULL

数据可以通过名字(字符串)或数值向量进行索引:

  • lst[["name"]]lst["name"]
  • lst[c(1,3,5)]lst[1:3]

还可以通过真值的Mask方式索引:

> lst[lst < 0]

抽取矩阵的行或列:

# 抽取结果为向量
> vec <- mat[1,] # First row
> vec <- mat[,3] # Third column

# 抽取结果仍为矩阵
> row <- mat[1,,drop=FALSE] # First row in a one-row matrix
> col <- mat[,3,drop=FALSE] # Third column in a one-column matrix

抽取数据框的行或列:

tmp <- dfrm[1]  #抽取一列,结果仍为data.frame
tmp <- dfrm[, 1, drop=FALSE]  #抽取一列,结果仍为data.frame
tmp <- dfrm[,1] #抽取一列,结果为向量

tmp <- dfrm[1,] #抽取一行,结果仍为data.frame(不能直接抽取出向量,由于每个元素类型不同)

# 抽取第一列的前两个元素(结果为向量)
tmp <- dfrm[1][1:2,]
tmp <- dfrm[1:2, 1]

# 抽取第一列的前两个元素(结果仍为data.frame)
tmp <- dfrm[1:2,][1]
tmp <- dfrm[1][1:2,,drop=FALSE]
tmp <- dfrm[1:2, 1, drop=FALSE]

# 抽取多列时,结果仍为data.frame(由于列类型可能不同的缘故)
tmp <- dfrm[1:2, 1:2]

利用列名创建“字典”:

# 向量
vct <- c()
vct['abc'] <- 123

# 列表
lst <- list()
lst[["abc"]] <- 1 : 3

删除元素的方法

通过负索引删除

vl = vl[-3]

从列表中删除

> years[c("Carter","Clinton")] <- NULL

# 删除NULL元素
> lst[sapply(lst, is.null)] <- NULL

# 删除满足条件的元素
> lst[lst < 0] <- NULL

数据分割与合并

命令 功能 备注
rbind 行合并  
cbind 列合并  
merge 列合并 用于data frame
subset 抽取子集 subset(airquality, Temp > 80 & is.na(Solar.R))
append 插入元素 用于向量
stack    
split 数据分组 用于向量
airquality$Temp2 <- airquality$Temp #增加Temp2列
airquality$Temp <- NULL #删除Temp列

Top5 = subset(mvt, LocationDescription %in% TopLocations)
# 删除多余无关的levels(Top5在执行了subset之后会包含整个集合的levels)
Top5$LocationDescription = factor(Top5$LocationDescription)

CPS = merge(CPS, MetroAreaMap, by.x="MetroAreaCode", by.y="Code", all.x=TRUE)

运算符和优先级

Operator Meaning
[ [[ Indexing
:: ::: Access variables in a name space
$ @ Component extraction, slot extraction
^ Exponentiation (right to left)
- + Unary minus and plus
: Sequence creation
%any% Special operators
* / Multiplication, division
+ - Addition, subtraction
== != < > <= >= Comparison
! Logical negation
& && Logical “and”, short-circuit “and”
| || Logical “or”, short-circuit “or”
~ Formula
-> ->> Rightward assignment
= Assignment (right to left)
<- <<- Assignment (right to left)
? Help

%any%运算符:

  • %%:求模,7%%4=3
  • %/%:整数除,7%/%4=1
  • %*%:矩阵乘法;
  • %o%:外积;
  • %x%:Kronecker乘积;
  • %in%:匹配运算。

各种赋值符号:

  • <-=:环境内变量赋值,<-可用于任何地方,=只能用于顶层或者括号列表中的子表达式,对于变量赋值二者相同,对于调用函数的参数二者不同;
  • <<-->>:通常用于函数内,先查找父环境是否有该变量,若有其值被重新定义,若没有则相当于全局变量赋值;
  • 赋值传递:a <- b <- c <- 6
# <- 赋值,x会继续保留在环境中
mean(x <- 1:10)# [1] 5.5
x # [1] 1 2 3 4 5 6 7 8 9 10

# = 赋值,x不会继续保留在环境中
rm(x)
mean(x=1:10) #[1] 5.5
x #Error: object 'x' not found

# 在data.frame中,=赋值会保留变量作为列名,<-不会
dfrm <- data.frame(colx = 1 : 10) # 列名为colx
dfrm <- data.frame(colx <- 1: 10) # 列名为colx....1.10

控制流

函数

常用函数

View:以spreadsheet风格展示数据

str:查看对象结构

显示对象各属性。

summary:查看对象统计特性

显示最小值、分位数、最大值等数据,可以通过boxplot直观的显示。

table:按factor类型统计

#将Ozone(行)和Month(列)作为factor类型,统计同时满足两个条件样本的个数,以表格的形式显示。
with(airquality, table(Ozone, Month)) 

with(airquality,
   table(OzHi = Ozone > 80, Month, useNA = "ifany")) #若有NA则显示
with(airquality,
   table(OzHi = Ozone > 80, Month, useNA = "always"))#总是显示NA
with(airquality,
   table(OzHi = Ozone > 80, addNA(Month)))           #增加一列NA

hist:直方图

hist(sqrt(islands), breaks = 12, col = "lightblue", border = "pink")

boxplot:盒须图(box-and-whisker)

boxplot(count ~ spray, data = InsectSprays) # 横轴为spray,纵轴为count

boxplot图示

boxplot绘制如上图

  • box中的粗横线表示中位数(median);
  • box的下边和上边分别表示第一和第三四分位数(quartile),二者之间的距离称为四分位数间距(IQR,inter-quartile range),分位数用quantile函数计算,IQR用IQR函数计算;
  • 最下和最上的横线分别表示最小和最大值;
  • 小圆圈表示离群点(outlier)。

令$STEP = range\times IQR$($range$可通过boxplot设置),区间$[first\; quartile - STEP, third\; quartile + STEP]$之外的是离群点,大于$first\; quartile - STEP$的最小值为图中的最小值(minimum),小于$third\; quartile + STEP$的最大值为图中的最大值(maximum),当boxplot的参数range=0时,不探测离群点,显示实际的最大和最小值。

citation:在文献中引用R的包

citation("Rcpp")
toBibtex(citation("Rcpp"))

# @Article{,
#   title = {Rcpp: Seamless {R} and {C++} Integration},
#   author = {Dirk Eddelbuettel and Romain Fran\c{c}ois},
#   journal = {Journal of Statistical Software},
#   year = {2011},
#   volume = {40},
#   number = {8},
#   pages = {1--18},
#   url = {http://www.jstatsoft.org/v40/i08/},
# }

Idiomatic R

循环法则(recycling rule)

当两个向量长度不一致时,通过循环补齐法则,解决对应元素之间(element-by-element)的运算,循环补齐方式如下:

recycling rule

> (1:6) + (1:3) 
[1] 2 4 6 5 7 9

> (1:6) + 10
[1] 11 12 13 14 15 16

> cbind(1:6, 1:3) 
    [,1] [,2]
[1,]   1    1 
[2,]   2    2 
[3,]   3    3 
[4,]   4    1 
[5,]   5    2 
[6,]   6    3

当长向量不是短向量倍数时,会有警告信息。

> (1:6) + (1:5) # Oops! 1:5 is one element too short 
[1] 2 4 6 8 10 7
Warning message:
In (1:6) + (1:5) :
    longer object length is not a multiple of shorter object length

批处理函数

####tapply:应用函数操作分组数据

tapply

# 将warpbreaks[,-1]强制转换为factor类型;
# 通过warpbreaks[,-1]对warpbreaks$breaks分类;
# 将每类的warpbreaks$breaks作为函数sum的输入;
# ……
tapply(warpbreaks$breaks, warpbreaks[,-1], sum)

实用技术

read.csv自定义格式读入数据

setAs("character","myDate", function(from) as.Date(from, format="%d/%m/%Y") )

tmp <- c("1, 15/08/2008", "2, 23/05/2010")
con <- textConnection(tmp)

tmp2 <- read.csv(con, colClasses=c('numeric','myDate'), header=FALSE)
str(tmp2)

其它

# 日期转换
DateConvert = as.Date(strptime(mvt$Date, "%m/%d/%y %H:%M")) #日期转换
mvt$Month = months(DateConvert)
mvt$Weekday = weekdays(DateConvert)

行业应用

机器学习

rattle包

数据集处理

  • sample.split:[caTools]将数据分为训练集合测试集;
  • complete(mice()):[mice]数据补齐;
  • [CROC]:ROC曲线。

回归分析

  • lm:线性回归;
  • glm:logistic回归。

模型优化

  • step:基于AIC的模型选择。

目录

参考资料

  1. [1]P. Teetor, R Cookbook. "O’Reilly Media, Inc.", 2011.

脚注

  1. Note that in the C code underlying R, all objects are pointers to a structure with typedef SEXPREC; the different R data types are represented in C by SEXPTYPE, which determines how the information in the various parts of the structure is used. 


打赏作者


上一篇:CS231n(4):最优化     下一篇:模式发掘(1):基本概念