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.frameas.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.exprif … else句型
for (var in seq) exprfor循环
while(cond) exprwhile循环
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,23456)
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的公式】
    
Yunze Liu
Yunze Liu
Bioinformatics Sharer

Co-founder of Bioinfoplanet(生信星球)

Next
Previous

Related