035-R Brain Storm
刘小泽写于18.9.16
写了几天的函数修修补补,基本框架有了,但是发现一些基础知识还是没有掌握牢固。不怕,学就是了!
Part1 零零散散的前言
R的运行模式?
交互模式:例如R studio左下角带'>'符号的
批处理模式:左上角写脚本的地方
R向量:如
x <- c(2,3,4)
c表示“连接”(concatenate);向量元素索引(下标)从1开始画直方图时可以通过设定breaks来改变分组
hist(Nile, breaks = 15)
调用q()退出R
R的核心是编写“函数”,所谓函数,就是一组指令的组合,来完成数据读取、执行计算、返回结果的任务
%%
是求余数运算用的,叫做求模运算符lm()
函数是求线性模型,格式为lm(V2~V1+V3)
就是用第一列V1和第三列V3来预测第二列,这里的+不是代表加和,仅仅是预测变量的分隔符。拟合过程采用最小二乘法完成,预测方程是:V2代表的预测值 = β0 + β1 x V1代表的预测值
。使用attributes()函数可以列出所有组件,β的保守值储存在coefficients中如果希望每次R启动都执行一些命令,就可以把这些命令存到.Rprofile中,对R进行配置时可以使用
options()
函数,另外.libPaths
可以在R的搜索路径中添加一个包含全部辅助包的目录获取R的帮助: 查询指定函数,如
?paste
; 获得运算符的帮助信息,需要将特殊字符和一些保留字用括号括起来,?">"
,或者要查看for循环的讲解?"for"
; 对于不懂的命令如paste,可以用example(paste)
来运行示例代码; 如果不清楚要查什么,但是目的比如是找能做多元正态分布的函数,可以用??("multivariate normal")
; 获得整个包的信息:help(package=dplyr)
网络搜索指定脚本:filetype:R DeSeq2 -rebol
, -rebol作用是查找R但排除和R相近后缀的REBOL编程语言结果R语言编程戒律之一就是:尽量避免使用循环,如果一定要用,就要循环简洁
#实现同样的功能,但第二个比第一个要好 for(i in 1:length(x)){ if(x[i] %% 2 == 1) k<-k+1 #对x进行遍历,当x是奇数时,k增加1 } ### for(n in x){ if(n %% 2 == 1) k<- k+1 } return(k) #return的目的就是把计算结果返回给调用它的代码
命名函数时,一般都会
xixi <- function(x){}
其中x时形式参数(formal argument/parameter),当实际使用函数时,在xixi()
中填的才是实际参数( actual argument)变量作用域:只在函数内部有效的叫做“局部变量”【比如形式参数】;函数内外均能使用叫“全局变量”。利用
<<
超赋值运算符(superassignment operater)可以在函数内部赋予“全局变量”的光荣称号编写函数时,经常会用到默认参数:
xixi <- function(x, y=1, z=F)
进行函数运算时,x是肯定要指定的,但是y、z可以不指定,他们已经有了默认值,当然啦,如果指定y或者z,就会覆盖之前的值R的重要数据结构:向量、字符串、矩阵、列表、数据框、类
向量:R核心成员。 向量中的元素必须是某种数据类型(不能混搭),比如一个向量由3个整数元素组成,或者由2个字符串组成,但不能由1个整数1个字符串组成。 所谓的“标量”,也就是单个的数,它实际上还是一个元素的向量
字符串:字符模式(而非数值模式)的单元素向量 字符操作函数有很多,比如paste、strsplit
x <- paste("xixi", "huahua","doudou") #组合 > x [1] "xixi huahua doudou" > y <- strsplit(x," ") #拆台 > y [[1]] [1] "xixi" "huahua" "doudou"
矩阵:向量加上两个附加属性:行数、列数
> a <- rbind(c(5,2,0),c(5,2,0)) > a [,1] [,2] [,3] [1,] 5 2 0 [2,] 5 2 0 #本来c(5,2,0)是向量,然后被赋予了空间位置,就成了二维的 #矩阵使用双下标作为索引 a[1,1] => 5
列表:它也是值的容器,只不过进化的地方在于其中的各项可以属于不同的数据类型。列表可以想象成一个个零件拼起来的一个积木,每个积木可以是不同类型的,有塑料的、木头的(表示数值型、字符型),每个积木叫做一个组件
> doudou <- list(x = "huahua", y = c(5,2,0)) > doudou $x [1] "huahua" $y [1] 5 2 0 #注意它是用$符号来访问列表中的元素 > doudou$x # 表示:取出列表doudou中的x组件 [1] "huahua"
一般好的程序设计师都会把函数返回的信息打包到一个列表中,然后通过
$
来访问 若要打印列表,就可以用str()
函数,显示很详细的R对象内部结构【不限于列表哦】> str(doudou) List of 2 $ x: chr "huahua" $ y: num [1:3] 5 2 0
数据框:数据库更是可以包含多种数据类型,并且方便调用,创建数据库可以用
data.frame(list())
,不过一般用read.csv
读取的文件就已经是数据框格式了类:首先要知道R是面向对象的编程语言,大多数R的对象是基于S3类(也就是S语言第三代,它是R语言的灵感源泉)
Part2 R的基础函数速查
刘小泽写于18.9.21
R中的输入输出
R的输入输出 | 作用 |
---|---|
load() | 加载save函数保存过的数据集 |
data(x) | 加载一些内置的数据集 |
read.csv() | 读取文本 |
save() | 保存对象 |
save.image() | 保存当前工作环境 |
paste0() | 连接对象 |
write.table() | 保存成数据框 |
# save & save.image
x <- stats::runif(20)
y <- list(a = 1, b = TRUE, c = "oops")
save(x, y, file = "xy.RData")
save.image() # creating ".RData" in current working directory
# paste & paste0
> paste("1st", "2nd", "3rd", sep = ", ")
[1] "1st, 2nd, 3rd"
> paste0("1st", "-2nd", "-3rd")
[1] "1st-2nd-3rd"
R是一种基于对象(Object)的语言,对象具有很多属性(Attribute),其中一种重要的属性就是类(Class),最基本的类包括了数值(numeric)、逻辑(logical)、字符(character)、列表(list),符合类包括矩阵(matrix)、数组(array)、因子(factor)、数据框(dataframe)
创建数据
R创建数据 | 作用 |
---|---|
from:to | 连续数字(如:1:4) |
seq(from, to, by) | 从from到to,中间以by为间隔 |
matrix() | 创建矩阵 |
rep(x,times) | 把x从头到尾重复几次 |
rep(x,each) | x中的每一个字符重复几次 |
list(a=c(1,2), b="hi”) | 创建多种向量的组合(字符、数值、逻辑等) |
rbind()/cbind() | 按行/列组合 |
factor() | 向量变因子 |
expand.grid() | 将向量或因子组合成数据框 |
gl() | 产生因子 |
# seq(from, to, by)
> seq(1,10,2) #间隔为整数
[1] 1 3 5 7 9
#间隔不是整数
seq(1.1 , 2,length=10)
[1] 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0
# matrix
> mdat <- matrix(c(1,2,3, 11,12,13), nrow = 2, ncol = 3, byrow = TRUE, dimnames = list(c("r1", "r2"),c("C.1", "C.2", "C.3")))
> mdat
C.1 C.2 C.3
r1 1 2 3
r2 11 12 13
# rep
> rep(c(1,2,3),times=2)
[1] 1 2 3 1 2 3
> rep(c(1,2,3),each=2)
[1] 1 1 2 2 3 3
# expand.grid
require(utils)
> expand.grid(height = seq(60, 80, 5), weight = seq(100, 300, 50),sex = c("Male","Female"))
# gl
> gl(2, 3, labels = c("Control", "Treat"))
[1] Control Control Control Treat Treat Treat
Levels: Control Treat
提取数据
R提取向量 | 作用 |
---|---|
x[n] | 提取x中第n个元素 |
x[-n] | 去掉第n个 |
x[1:n] | 取出前n个 |
x[-(1:n)] | 取出第n个到最后一个 |
x[x>1 & x<3] | 取出1到3之间的 |
x[ x %in% c(“dou”,“hua”,“xi”)] | 取出指定集合中的 |
R提取列表 | 作用 |
---|---|
x[1] | 取出列表x的第一列【一个列表有多列,每列有多个元素】 |
x[[1]] | 取出列表x的第一个元素 |
x[[“name”]] | 指定提取名称 |
R提取矩阵/数据 | 作用 |
---|---|
x[i,j] | 取i行j列 |
x[, c(1,4)] | 取1和4列 |
x[“name”,] | 取行名为“name”的 |
x[[“name”]] | 【数据框特有】取“name”的列 |
变量转换与信息查询
转换都是以as
开头,然后加转换类型,如as.data.frame
、as.numeric
查询以is
开头,结果返回逻辑值(TRUE/FALSE)
length(x) #x中元素个数
dim(x) #查询或设置几行几列
dimnames(x) #查询或设置行/列名
nrow、ncol #行数/列数
class(x)#查属性
attr(x,which)#设置x的属性
> x <- 1:10
> attr(x,"dim") <- c(2, 5)
> x
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 10
数据筛选
R数据筛选 | 作用 |
---|---|
which.max() | 取x的最大值 |
which.min() | 取最小值 |
rev() | 把x的元素反转 |
sort() | 从小到大排序【从大到小用rev(sort(x))】 |
match(x,y) | 相当于%in%的效果 |
which(x == a) | 返回x中元素为a的坐标 |
na.omit(x) | 去掉x中缺失值NA |
na.fail(x) | 如果出现一个NA,就报错 |
unique(x) | 去掉x中重复值 |
table(x) | 对x的元素进行统计 |
subset() | 取子集 |
sample(x, size) | 抽样(有放回和不放回)size指定抽样量 |
> x <- c(1,2,3,4,1)
# which 它会返回真值的位置
> which(x == "1")
[1] 1 5
> which.max(x)
[1] 4
# unique
> unique(x)
[1] 1 2 3 4
#subset
subset(state.x77, grepl("^M", nm), Illiteracy:Murder)
#【对于数据框state.x77,取出行名开头是“M”的,列从Illiteracy到Murder的子集】
subset(airquality, Day == 1, select = -Temp)
#【对于数据框airquality,取出Day值为1的,并且去掉Temp列】
#sample
> sample(1:10, replace = TRUE) #【放回抽样】
[1] 4 9 10 7 6 10 9 1 10 5
数值计算
R数值计算 | 作用 |
---|---|
range(x) | 得到最值 |
quantile(x) | 四分位数 |
sd(x) | 标准差 |
cor(x) | 计算相关矩阵(当x为向量时为1) |
round(x) | 保留小数位数 |
scale(x) | 进行数据的中心化和标准化 |
cumsum(x) | 累加 |
union(x,y) | 并集 |
intersect | 交集 |
Mod(x) / abs(x) | 两种方法:绝对值 |
var() / cov() | 方差/协方差 |
还有一些常见的计算函数:
log(),log10(),exp(),max(),min(),sum(),mean(),median()
矩阵操作
R矩阵 | 作用 |
---|---|
t(x) | 转置 |
diag(x) | 对角矩阵 |
colMeans(x) / rowMeans(x) | 求均值 |
colsum(x) / rowsum(x) | 求加和 |
字符串处理
R字符串 | 作用 |
---|---|
paste | 连接向量 |
substr(x, start, stop) | 提取子字符串 |
grep(pattern, x) | 查找 |
gsub(pattern, replacement, x) | 替换 |
tolower(x)/ toupper() | 变小/大写字母 |
nchar(x) | x中每一个元素的字符数(如:43就是2个字符) |
# substr
> substr("abcdef", 2, 4)
[1] "bcd"
> substring("abcdef", 1:6, 1:6)
[1] "a" "b" "c" "d" "e" "f"
条件控制
R编程 | 作用 |
---|---|
function(args){expr} | ()指定参数【通过formals()调取】 {}指定函数本体【通过body()调取】 |
return(value) | 返回值 |
if (cond) expr | 满足条件就 |
if (cond) cons.expr else alt.expr | if … else句型 |
for (var in seq) expr | for循环 |
while(cond) expr | while循环 |
break | 终止for、while循环 |
next | 跳过循环的当前迭代而不终止它 |
ifelse(test, yes, no) | test为真,输出yes值,否则输出no值 |
do.call(FUN,args) | 给列表或数据框一个函数,让它里面的所有元素都执行 |
# 关于next
x <- letters[1:6]
for ( i in x) {
if (i == "d") {
next
}
print(i)
}
# 结果返回除了d的其他字母
#关于ifelse
x <- c(1,2,3,4,5,6)
ifelse(x != 1, 1, 0) #如果x的值不等于1,输出1,否则输出0
[1] 1 0 0 0 0 0
#关于do.call
#当要执行函数的接受参数太多,就可以用do.call
x <- list(matrix(1:20, ncol=4), matrix(5:25,ncol=4),matrix(10:30,ncol=4))
x_sum <- do.call(sum,x)
Part3 向量
这是R中最基本的数据类型了,当然矩阵也是向量的一种特例(长向量)
R语言中,变量的类型称为模式,有整型、数值型、字符型、逻辑型等,使用
typeof(x)
查询向量是连续存储的,不能插入或者删除,如果想更改需要重新赋值。比如将向量存储为x,那么x相当于一个指针,而重新赋值就是将x指向新的向量
循环补齐:对两个长度不等的向量进行运算,需要重复较短的那个向量,知道和长的向量长度匹配
向量索引是
向量1[向量2]
关于运算符优先级:括号大于冒号大于加减号,例如
1:2-1结果是0 1
all(con)
必须全部满足条件con才能输出为TRUE,any(con)
至少一个满足条件就输出为TRUE多个向量输入的情况,可以输出为矩阵,利用sapply函数可以实现
> x <- function(x) return(c(x,x^2)) #先定义函数 > sapply(1:4,x) # 批量运行得矩阵 [,1] [,2] [,3] [,4] [1,] 1 2 3 4 [2,] 1 4 9 16
NA表示缺失值(存在但未知),NULL表示不存在的值;一般使用
na.rm
来跳过缺失值,而NULL会自动跳过> x <- c(1,4,5,12,NA) #存在NA的情况 > mean(x) [1] NA > mean(x,na.rm = T) [1] 5.5 > y <- c(1,4,5,12,NULL) #存在NULL的情况 > mean(y) [1] 5.5
筛选:
subset()
可以自己移除NA;which
可以返回满足条件的索引,但比较浪费资源,因为它需要每一个都测试一遍,才能得到结果向量界的if-then-else结构:
ifelse(b,u,v)
他比传统结构速度要快,得益于向量化,并且可以嵌套使用# b是布尔型向量(用作判断),u、v是一般向量 x <- c(2,5,9,10) ifelse(x>5, x+1, x-1) #结果就是1 4 10 11【前两个不满足判断条件,于是使用x-1的公式】