【R语言】基础知识

R 语言是一门动态弱类型的语言,同时作为一种解释型程序语言,它具有面向对象编程和函数式编程两种编程范式。

其中面向对象的部分中,将对象作为存储单位,用以存储变量值,存储函数内容,存储字符内容等。 如果在命令行中进行交互时输入对象所相关的变量名,会返回对象内存储的内容。 当调用函数时,需要使用 $lambda$ 表达式的方式。

面向对象编程的思想下,每个对象都有其相应的属性,大部分属性是普适的,也有特殊的属性值。

{% asset_img “oop.png” %}

注意

  1. R里最基础的数据元素不是标量,是向量,所有数据传入变量时均转换为向量组成。
  2. 在查看对象的类型时,对于单向量对象,返回每个元素的数据类型;对于向量之外的对象,返回数据结构。

函数式编程的部分则将函数作为编程的主体,对将函数和环境作为编程考虑的因素。 函数式编程中,函数是一等公民,或者说将函数看作一种对象,可以将函数作为参数传递给高阶函数,并且高阶函数可以将函数作为一个返回值。

1. 数据类型

R 中变量的声明通常为

变量名 = 对象
#或
变量名 <- 对象

变量名命名有一些基本原则:

  • 必须字母开头。
  • 可包含字母、数字、_.
  • ==区分大小写==。
  • 不能使用关键字,最好不
  • 不能以特殊字符开头,最好不
  • 不能以数字开头,最好不 之所以用最好不,是因为在是在迫不得已的时候,可以用 "' 和反引号来包裹变量名,从而把他们作为变量名,但是使用的时候也得这样用。

常量或称字面量,即编程实践中的值。 数据类型,即字面量类型。根据数据结构复杂程度可以分为,基本类型复合类型

1.1. 基本类型

通过 mode() typeof() 获得

  • 字符型(character):"a", 'a'
  • 数值型(numeric)
    • 整数(integer):1L
    • 浮点数(double):3.14
    • 复数型(complex): ,统计中基本不使用
  • 逻辑型(logical):TRUE
  • 原生型(raw): ,仅在需要包含二进制数据时使用

有些时候 R 会自动进行类型之间的转换,此时遵循类型转换优先级进行:

  1. 字符型
  2. 浮点型
  3. 整型
  4. 逻辑型

1.2. 复合类型

1.2.1. 标量(Scalar)

只储存仅有一个变量的对象,R中现实不存在

x <- 1
y <- "a"
z <- TRUE

1.2.2. 向量(vector)

存储多个标量,但是类型统一,有一维和多维向量。

a<-seq(from=1,to=10)
a
#> [1]  1  2  3  4  5  6  7  8  9 10

a[-c(1,2,3)] #负号表示不取这个位置的元素,可以用来删除数据
#> [1]  4  5  6  7  8  9 10

a[1] #取得向量a里面的第一个元素
#> [1] 1

a[1:3]
#> [1] 1 2 3

注意

  1. ==索引不从0开始,而是从1开始==
  2. 索引0用以规避NA
  3. 除了用索引,向量每个元素也可以有 names
  4. 对于拥有不同类型的向量合并时,会自动进行类型转换
矩阵(matrix)

每个元素都拥有相同的数据类型(数值型、字符型或逻辑型),==是维度属性为 2 的向量==。在 R 中是一种相对原始的数据结构。

# 其中,data是一个向量数据;
# nrow是矩阵的行数;
# ncol是矩阵的列数;
# nrow与ncol的乘积需等于data向量的长度
# 当byrow=TRUE时,生成矩阵的数据逐行放置,默认值byrow=FALSE,数据逐列放置;
# dimnames是数组维的名字,默认值为空。可以输入包含行名、列名的一个list,对数值行名、列名进行命名
matrix(
	data=NA,
	nrow=1, ncol=1,
	byrow=FALSE,
	dimnames=NULL
)

#nrow行数,ncol列数,byrow按行排列,dimnames对行和列进行命名
col_name=c("A","B","C")#编辑列名
row_name=c("M","N")#行名
y=matrix(1:6,nrow=2,ncol=3,byrow=TRUE,dimnames = list(row_name,col_name))

y
#>   A B C
#> M 1 2 3
#> N 4 5 6

#对y进行转置,好像列名和行名也发生了变化
y1=t(y) 
y1
#>  	 [,1] [,2]
#> [1,]    1    4
#> [2,]    2    5
#> [3,]    3    6

注意

  1. 使用matrix[1],取得是一个值(按照列进行逐列排序的)
  2. 行名和列名不在任意行和列中
  3. 不支持使用 $ 取子集
  4. 如果使用 names() 来进行列名操作,结果会发现,这个列名与你所预期的列名不一致,它是每一个元素自左上逐列进行排序的命名
数组(array)

==维度属性>2的向量,每个元素(g)只能有一种数据类型,不同元素的类型可以不同==。

#其中,data是一个向量数据;
#dim是数组各维的长度,默认值为原向量的长度;dimnames是数组维的名字,默认值为空。
array(
	data=NA,
	dim=length(data),
	dimnames=NULL
)

#创立一个三维的数组,dimnames对名字进行命名
dim1=c("A1","A2")
dim2=c("B1","B2","B3")
dim3=c("C1","C2")
z=array(1:12,c(2,3,2),dimnames = list(dim1,dim2,dim3))

z
#> , , C1
#> 
#>    B1 B2 B3
#> A1  1  3  5
#> A2  2  4  6
#> 
#> , , C2
#> 
#>    B1 B2 B3
#> A1  7  9 11
#> A2  8 10 12

注意

  1. 行名和列名不在任意行和列中
因子(factor)

用于对数据进行自动分组,自动上色,==分类变量==。

==因子是带有水平(level)属性的向量,是一类分类离散变量==。

由于拥有 class 属性,它也是 S3 对象。

{% asset_img “facters.png” %}

# x是向量
# levels是水平,可以自行制定各离散取值,默认取x的不同水平值;
# labels用来指定各水平的标签,默认用各离散取值的对应字符串;
# exclude参数用来指定要转化为缺失值(NA)的元素值集合,如果指定了levels,则当因子的第i个元素等于水平中的第j个元素时,元素值取”j”,如果它的值没有出现在levels中,则对应因子元素取NA;
# ordered取值为真(TRUE)时,表示因子水平是有次序的(按编码次序),否则(默认值)是无次序的。
factor(
	x,
	levels=sort(unique(x),na.last=TRUE),
	labels,
	exclude=NA,
	ordered=FALSE
)

# 检验对象是否是因子
is.factor()

# 把一个向量转化成一个因子
as.factor()

# 作为 factor 的一类特殊子集 有序factor 将水平(level)划分出了高低顺序
ordered(x, levels=c())
时间序列(ts)

包含 Date Date-timesDurations,都是 S3

🧐还没研究。。。

1.2.3. 列表(list)

可包含所有的数据结构,数据框的子集是以列表的方式呈现。

每一个元素都是一个指针,指向对应元素的内存地址。从某种意义上来讲,列表也是一种向量。

注意:

  1. 列表并不会展平整个数据结构,这点与向量是不同的
  2. unlist() 虽然可以展平一个列表,但是结果并不一定会如你预期,所以尽可能的就用 c()
数据框(data frame)

常见的二维数据表格,==由向量和或因子组成的一个列表,长度一致,数据类型可以不一致== data.frame 假定每列是一个变量,==且具有相同的长度==,每行是一个观测值。

patientID<-c(1,2,3,4)
age<-c(22,13,42,21)
diabetes<-c("t1","t2","t3","t4")
status=c("poor","improved","poor","excellent")
status=factor(status,order=TRUE,levels=c("poor","improved","excellent"))

patientData<-data.frame(patientID,age,diabetes,status)
patientData
#>   patientID age diabetes    status
#> 1         1  22       t1      poor
#> 2         2  13       t2  improve
#> 3         3  42       t3      poor
#> 4         4  21       t4 excellent
#实例标识符可以通过数据框操作函数中的rowname选项指定

注意

  1. 使用dataframe[,1],返回当前列的==向量==
  2. 使用dataframe[1],返回当前列的==数据框==
  3. 使用dataframe[1,],返回当前行的==数据框==
  4. 行名和列名不在任意行和列中
  5. 如果想在数据框中嵌入一个列表需要使用 I() 对数据进行包裹
Tibble

由于现在数据分析中对于数据框的使用和以往的不同,导致现在使用数据框存在很多烦恼,因此诞生了 tibble 这个类型。

对比数据框 tibble 的不同有:

  1. 与数据框的结构类似,但是相对与数据框拥有更多的返回信息,以及更多的懒加载机制
  2. 没有行名,所以 tibble 类型提供了行名转换的接口,tibble(rownames="") 以及 rownames_to_colume()
  3. 取子集时保持行为的一致性,如 tibbl[, var]tibble[var] 的结果保持一致,都是 tibble;tibble$var 时取得的都是一个向量
  4. 不会无端自发扩展,在进行 tibble$x 时,不会自动对 x 进行模糊匹配
  5. 当构建一个 list-colume 时不再需要 I() 进行包裹

总结

{% asset_img “summary02.png” %} {% asset_img “summary01.png” %} {% asset_img “R_Vector.png” %}

对象可包含类型同一对象能否有多种类型
向量ALLF
因子数值、字符F
数组ALLF
矩阵ALLF
数据框ALLT
列表ALL、函数、表达式T
时间序列ALLF

1.3. 特殊对象

  • NaN
    Not A Number 非数字
  • NA
    Not Allow 非法值,缺失数据
  • Inf
    无穷大,可加正负

2. 其他常见属性

  • 长度:通过length()获得
  • 类属:通过class()获得
  • 名:通过names()获得
  • 维度:通过dim()获得

4. 基本运算

  • +-*/%%取余 %/%取整除
  • ^
  • 声明和赋值
    =<- 同样赋值,但是作用不同
    参数定义,赋值/传参:=
    变量定义,传参:<-
  • ' "作用一致
    单引号内可以有双引号,双引号内可以有单引号
运算符描述
&元素逻辑与运算符,将第一个向量的每个元素与第二个向量的相对应元素进行组合,如果两个元素都为 TRUE,则结果为 TRUE,否则为 FALSE。
元素逻辑或运算符,将第一个向量的每个元素与第二个向量的相对应元素进行组合,如果两个元素中有一个为 TRUE,则结果为 TRUE,如果都为 FALSE,则返回 FALSE。
!逻辑非运算符,返回向量每个元素相反的逻辑值,如果元素为 TRUE 则返回 FALSE,如果元素为 FALSE 则返回 TRUE。
&&逻辑与运算符,只对两个向量对第一个元素进行判断,如果两个元素都为 TRUE,则结果为 TRUE,否则为 FALSE。
||逻辑或运算符,只对两个向量对第一个元素进行判断,如果两个元素中有一个为 TRUE,则结果为 TRUE,如果都为 FALSE,则返回 FALSE。

5. 操作符

""
''
;           #语句分割,相当于换行
\           #
$           #$对应的是S3类,$比较常用
            #$表示从一个dataframe中取出某一列数据
@           #@对应的是S4类,@比较少用
            #@是从R的类实例里面读取数据
            # bg=x@colors$bg.col就是从对象实例x中取出colors,
            # 而这个colors本身又是个dataframe,所以需要进一步用$读取bg.col列。
~           #分面时用以指定
.           #tidyverse中可以代表管道的输出
            #b <- a %>% .[5]
%		    #百分号
%%		    #取余
%/%		    #取整除
%*%		    #向量内积
%o%		    #向量外积
%in%	    #类似于in
            #向量运算时对每一个元素进行遍历
==          #判断
            #向量运算时进行循环补齐同时进行值的判断
%>%		    #管道
%$%		    #??
%<>%	    #??
%T>%	    #??

!!
:=

6. 发现R包

RDocumentation 搜索引擎,发现和了解 R 包和函数。

参考资料

小洁忘了怎么分身-生信技能树GEO分析课程 R语言数据对象类型-简书 R4beginner-cran R语言编程入门-PLoB Welcome | Advanced R