美文网首页R学习数据科学与R语言程序员
R语言基础(一):数据结构篇

R语言基础(一):数据结构篇

作者: 花若离枝rain | 来源:发表于2017-04-15 17:29 被阅读89次

由于本人学习R语言之前是个小白,所以这些东西都是以零基础的视角出发写下来的,学习R语言很重要的一点是了解R的数据结构(即用于存储数据的对象类型)有哪些,先按照个人要求的格式创建含有研究信息的数据集,这样才可以更好的对数据进行处理与分析。

1、介绍

R里面有五种数据结构:向量(vector)矩阵(matrix)数组(array)数据框(data frame)列表(list)。五种数据结构中,又可以简单分为两类(1)向量、矩阵、数组,这三种数据结构的相同点在于均只能包含同一种数据类型,即要么都是数值型,要么都是字符型或者其他的任意一种数据类型,而不同点在于维度(dim),向量是一维的,矩阵是二维(行、列)的,数组是二维及二维以上(行、列、层)的,其实这三种数据类型互相是一种包含关系,R语言最基本的数据类型就是向量,矩阵也是向量,只不过多了行row与列column的划分,矩阵同时也是一个特殊的数组,即第三个维度为1的数组。(2)数据框和列表,这两者相同的地方在于可以包含不止一种数据类型,不同点在于维度,数据框是二维的,列表是二维及二维以上的。即,数据框中不同的列可以是不同数据类型,而列表的不同层也可以是不同的数据类型。列表可以说是R中数据类型最为复杂的一种,列表可以是这五种数据结构的一个有序集合,列表的每一层可以是向量,可以是矩阵,可以是数组,可以是数据框,甚至是其他列表。

介绍完了五种数据结构,首先给出各个不同数据结构的示例,接下来讲讲这五种数据结构的常用操作的异同。

2、示例

向量

[1] 1 2 3 4 5

矩阵

      [,1] [,2] [,3] [,4]
[1,]    1    4    7  10
[2,]    2    5    8  11
[3,]    3    6    9  12

数组

     , , 1
      [,1] [,2]
[1,]    1    2
     , , 2
      [,1] [,2]
[1,]    3    4
     , , 3
      [,1] [,2]
[1,]    5    6

数据框

    patientID age diabetes    status
1              1  25    Type1      Poor
2              2  34    Type2  Improved
3              3  28    Type1 Excellent
4              4  52    Type1      Poor

列表

$title
[1] "My First List"
$ages
[1] 25 26 18 39
[[3]]
[,1] [,2]
[1,]    1    6
[2,]    2    7
[3,]    3    8
[4,]    4    9
[5,]    5  10
[[4]]
[1] "one"  "two"  "three"

3、创建

五种数据结构的创建都非常简单,而创建需要的函数其实就是名称本身(向量除外)。下面演示一下上面的例子是如何被创建出来的。

向量:向量的创建常用c函数,c函数是R中经常会使用到的一个函数

c(..., recursive = FALSE)

示例:

> a <- c(1,2,3,4,5)

矩阵:矩阵的创建常用matrix()函数

matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE,dimnames = NULL)

示例:

> b <- matrix(1:12,nrow=3,ncol=4) 

数组:数组的创建常用array()函数

array(data = NA, dim = length(data), dimnames = NULL)

示例:

> z <- array(1:24,c(1,2,3)) 

数据框:数据框的创建常用data.frame()函数

data.frame(..., row.names = NULL, check.rows = FALSE, check.names = TRUE, fix.empty.names = TRUE, stringsAsFactors = default.stringsAsFactors())

示例:

> patientID <- c(1,2,3,4)
> age <- c(25,34,28,52)
> diabetes <- c("Type1","Type2","Type1","Type1")
> status <- c("Poor","Improved","Excellent","Poor")
> patientdata <- data.frame(patientID,age,diabetes,status)

列表:列表的创建常用list()函数

list(...)

示例:

> g <- "My First List"
> h <- c(25,26,18,39)
> j <- matrix(1:10,nrow=5)
> k <- c("one","two","three")
> mylist <- list(title=g,ages=h,j,k)

:对于向量有一点需要注意的地方,在R中并没有标量之说,对于标量,在R中默认为一元向量。除了使用c函数,同样可以使用其名称vector()函数来创建。

vector(mode = "logical", length = 0)

示例:

> vector("character", 5)
[1] "" "" "" "" ""

使用vector函数时,创建了一个特定的数据类型和长度的向量,如果是数值型,默认填充数字0,如果是逻辑型,默认填充False,如果是字符型,默认为空。
此外,向量的创建还可以使用:冒号(colon operator)创建一个序列,sequences()函数用于生成等差序列,seq.int() 创建一个步长为赋予by的数值的等差序列,seq_along() 创建一个从从1开始,长度等于输入值长度的序列,seq_len()创建一个从从1开始,长度为输入值的序列

seq(from = 1, to = 1, by = ((to - from)/(length.out - 1)), length.out = NULL, along.with = NULL, ...)
seq.int(from, to, by, length.out, along.with, ...) 
seq_along(along.with) 
seq_len(length.out)

示例:

> 3.5:5.5    
[1] 3.5 4.5 5.5
> c(1,1:3,c(5,8),13)
[1] 1 1 2 3 5 8 13
> seq_along(c(3,4))
[1] 1 2

对于矩阵也有需要注意的地方,当给矩阵赋值时,赋值默认按而不是按行进行。

4、维度

向量length(),返回的是其中的元素的个数,也可以通过该函数给向量重新赋予新的长度,不足的部分用NA补齐,超过的部分会被删除。对于向量nrow()、ncol()返回NULL,可以使用NROW()和NCOL(),前者返回向量元素个数,后者恒为1(因为向量默认是一列)
示例:

> a
[1] 1 2 3 4 5
> length(a)
[1] 5
> length(a) <- 7
> length(a)
[1] 7
> a
[1]  1  2  3  4  5 NA NA
> length(a) <- 3
> a
[1] 1 2 3

矩阵length(),返回行与列的乘积,即其中包含的所有元素的个数
dim(),返回矩阵的维度,也可以通过dim函数给矩阵重新赋予不同的行列组合。
nrow()与ncol(),分别返回向量的行数与列数

数组length()、dim()、nrow()、ncol()
示例:

> length(patientdata)
[1] 4
> nrow(patientdata)
[1] 4
> ncol(patientdata)
[1] 4

数据框dim()、nrow(),但是length()与ncol()返回相同的值,因为数据框是不同列的组合

列表length()返回第三个维度,即有多少层。但是对于列表来说,dim()、nrow()、ncol()这三者不再有意义,会返回NULL(此时如果使用NROW()和NCOL()函数,不会返回NULL,但是此时这两个函数将列表看成向量,NROW()返回的是层,NCOL()只会返回1,因为向量只有一列)。
示例:

> length(mylist)
[1] 4

5、命名

向量names()函数可以对向量的中各个元素的名称进行查询,如果有,则返回对应的名称向量,如果没有,则返回NULL,而对于向量中各个元素的命名也是使用该函数。unname()可以去掉元素名

names(x)
names(x) <- value,

示例:

> names(a)
NULL
> names(a) <- c("one","two","three","four","five")
> a
one  two three  four  five
1    2    3    4    5

矩阵rownames()、colnames()、dimnames()可以对矩阵的行名、列名、所有名称进行查询,矩阵在定义时便有参数可以设置名称,dimnames=list(...)可以对矩阵的各行各列进行命名,也可以在矩阵创建之后再使用该函数命名或者修改

dimnames(x)
dimnames(x) <- value
rownames(x, do.NULL = TRUE, prefix = "row")
rownames(x) <- value
colnames(x, do.NULL = TRUE, prefix = "col")
colnames(x) <- value

数组:同上

数据框:当赋值给数据框的变量都有名称时,数据框会自动将变量名称赋给每一列的变量。如果不希望,可以使用参数row.names = NULL除去变量自带的名称。rownames()、colnames()、dimnames()则与矩阵相似,但是names()返回结果与colnames()相同。
示例:

> colnames(patientdata)
[1] "patientID" "age"       "diabetes"  "status" 

列表:从技术上讲,列表就是向量(都是一列,拥有多行元素,虽然不同行元素类型不同),所以对于列表的命名与向量相同

names(x)
names(x) <- value,

6、索引与筛选

向量:向量索引有四种方法,(1)、给向量传递一个正数x(表示位置,即第x行),返回从1到x列的所有列(R中第一列为1而非0)。(2)、给向量传递一个负数,返回除去该行的所有列。(3)、给向量传递逻辑值,返回所有逻辑值为TRUE的列。(4)、利用向量各个元素的名称进行索引。
索引符号为中括号[ ]
示例:

> a[2]
two 
  2 
> a["two"]
two 
  2 
> a[["two"]]
[1] 2

当向量各元素有名称时,按数字索引和名称索引都会使得输出结果带有名称,而如果希望输出结果不带名称时,可以使用双重中括号[[]]
使用上述方法,a[2:4]、a[-1]、a[c(FALSE,TRUE,TRUE,TRUE)]、a["two"]返回的结果相同。

此外,也可以利用条件对向量进行筛选,有三种方法:使用[]which()函数和subset()函数,[]返回逻辑值,which()返回的是满足条件的元素所处位置,而subset()是截取出符合条件的元素

> x <- c((1:5)^2,NA)
> x
[1] 1 4 9 16 25 NA
> x>5
[1] FALSE FALSE  TRUE  TRUE  TRUE    NA
> x[x>5]
[1]  9 16 25 NA
> which(x>5)
[1] 3 4 5
> subset(x,x>5)
[1]  9 16 25

可以看到使用[]和另两种方法的区别在与对NA的处理不同
也可以利用[]对向量中的元素进行重新赋值(R中的向量实际是连续存储的,不能插入也不能删除元素,向量的大小在创建时已经确定,更改的时候实际上是重新定义一个新的向量,然后再覆盖原向量)

> x[x>5] <- 0
> x
[1]  1  4  0  0  0 NA

矩阵:矩阵同样有上述四种索引方式,区别在于矩阵具有行列的属性,在索引时需要表现出

> b[1,3]
[1] 7
> b[2,]
[1]  2  5  8 11

矩阵的筛选操作与向量相同,但是which()函数返回的并不是矩阵,而是满足某一条件的所有元素组成的向量,而[]subset函数返回的依然是筛选出来的子矩阵(对于所有数据结构而言,如果返回的是一行元素会被R默认当作向量处理,使用drop=FALSE参数可以防止返回向量)。
也可以利用与向量相同的筛选的方式对某一个元素、某一行、某一列或者满足条件的所有元素进行重新赋值。

> b[b>7]
[1]  8  9 10 11 12
> b[b>7]<-0
> b
     [,1] [,2] [,3] [,4]
[1,]    1    4    7    0
[2,]    2    5    0    0
[3,]    3    6    0    0
> b[,2]>4
[1] FALSE  TRUE  TRUE
> b[b[,2]>4,]
     [,1] [,2] [,3] [,4]
[1,]    2    5    8   11
[2,]    3    6    9   12
> which(b>3)
[1] 4 5 6 7  8  9 10 11 12
> subset(b,select=1,drop=FALSE)
     [,1]
[1,]    1
[2,]    2
[3,]    3

需要注意的是,使用于向量的运算也都适用于矩阵,因为矩阵也是向量

数组subset()函数不能用于数组,[]which的操作与矩阵相同

数据框:适用于向量的索引方式同样适用于数据框,此外,如果希望输出不带名称的结果,可以适用双重中括号[[]]或者美元符号$,而对于筛选方式(中括号[]which()函数、subset()函数),不仅需要注意行与列,同时也应该注意数据框可能含有多种数据类型,当按条件进行筛选时最好指定到相应的列

> patientdata$age
[1] 25 34 28 52

patientdata$a、patientdata[["age"]]可以返回相同的结果。

> which(patientdata$age>26)
[1] 2 3 4

列表:适用于向量的索引方式同样适用于数据框,此外,如果希望输出不带名称的结果,可以适用双重中括号[[]]或者美元符号$,与向量不同的是列表可以进行嵌套索引

> mylist[1:2]
$title
[1] "My First List"
$ages
[1] 25 26 18 39

mylist[c(-3,-4)]、mylist[c("title","ages")]、mylist[c("TRUE","TRUE","FALSE","FALSE")]这三者与上述返回结果相同

> mylist[[4]][[1]]
[1] "one"
> mylist$title
[1] "My First List"

等价于mylist[[1]]、mylist[["title"]]、mylist$t
值得注意的是,当索引列表中不存在的一项元素时,适用双重中括号直接索引会返回error,其他索引方式返回NULL

> mylist["fi"]
$<NA>
NULL
> mylist[[5]]
Error in mylist[[5]] : 下标出界

7、运算

(之后会详细讲数据分析,所以在此只略讲)
R中的运算符有:

算术运算符 含义
+
-
*
/
^
**
x%%y 余数
x%/%y 整除
逻辑运算符 含义
< 小于
> 大于
<= 小于等于
>= 大于等于
== 严格等于
!= 不等于
!x 非x
x&y x和y
x&$y x和y (针对标量)
isTRUE(x) 测试x是否为TRUE

向量:向量的算术运算实际上两个向量间两两对应元素的运算,当两向量长度相同时,一一对应即可,长度不同时,如果两者长度为整数倍,则较短的向量自动扩展

> a
  one   two three  four  five 
    1     2     3     4     5 
> m <- c(3,4)
> a+m
  one   two three  four  five 
    4     6     6     8     8 
Warning message:
In a + m : 长的对象长度不是短的对象长度的整倍数
> m <- c(3)
> a+m
  one   two three  four  five 
    4     5     6     7     8 

矩阵:矩阵与向量相加只需要为整数倍,向量会自动扩展。如果两矩阵相加则要求维度相同

数组:与矩阵相同

数据框:略

列表:略

8、其他

any()函数和all()函数分别报告其参数是否至少有一个或者全部为TRUE
当直接对向量适用比较运算符时返回的是布尔逻辑向量
c()函数可以直接合并两个不同维度的矩阵、矩阵和向量并返回一个向量,也可以合并列表和向量,返回列表(其中向量中每个元素被转换成列表),也可以合并列表和矩阵,返回列表(其中矩阵中的每个元素都被转换成列表)
as.list()可以把向量转换成列表
unlist()把列表转换成向量
rep()函数用重复的元素创造向量,times参数表示重复的次数,length.out参数表示输出长度,each参数表示每一个元素重复的次数

rep(x, ...)
rep.int(x, times)
rep_len(x, length.out)
> rep(1:5)
[1] 1 2 3 4 5
> rep(1:5,3)
 [1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
> rep(1:5,each=3)
 [1] 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5
> rep.int(1:5,3)
 [1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
> rep_len(1:5,3)
[1] 1 2 3

声明:该学习笔记的内容参考了《R in action》《R语言编程艺术》《Learning R》这三本书,是本人一点一点总结、一点一点敲出来的。写下这个学习笔记是为了督促自己更好的学习、总结与巩固,也希望可以帮到需要帮助的人

相关文章

  • R语言-0基础学习4-实战1-常见操作

    R语言学习系列R语言-0基础学习1-数据结构R语言-0基础学习2-构建子集R语言-0基础学习3-循环排序信息处理函...

  • R基础与机器学习初探

    一.R语言基础 1.1 R的数据结构 向量、数据框、矩阵属于最常用的R数据结构,关于基础这里不多讲,简单概括一下 ...

  • R语言基础(一):数据结构篇

    由于本人学习R语言之前是个小白,所以这些东西都是以零基础的视角出发写下来的,学习R语言很重要的一点是了解R的数据结...

  • R语言编程基础第一篇:语法基础

    R语言编程基础第一篇:语法基础,已经更新结束,下面是文章目录: R语言入门资料 R语言基础教程——第1章:初识R ...

  • R语言常用函数整理(基础篇)

    R语言基础函数整理 R语言常用函数整理本篇是基础篇,即R语言自带的函数。 一、数据管理 vector:向量nume...

  • 《学习小组Day5笔记--寒鹤》

    R语言之数据结构 今天的学习内容是R语言的数据结构。R语言的数据结构主要有向量(vector),矩阵(matrix...

  • R和Python数据结构对比

    本文内容概要: R语言数据结构及实例操作 Python语言数据结构及实例操作 R语言数据结构及实例解析 接下开始学...

  • R语言---基础篇

    基础知识总结 小羊 前段时间,我一直在学习R语言,通过编程艺术和PPV课程,还有R实战,内容还没有学习完。 现在,...

  • R语言:基础篇

    一.R环境设置 尝试在线环境 你真的不需要设置自己的环境来开始学习R编程语言。 原因很简单,我们已经在线设置了R编...

  • R语言基础--数据类型-总结

    R语言基础--数据类型-总结 1、R语言基础--数据类型之向量 2、R语言基础--数据类型之因子 3、R语言基础-...

网友评论

    本文标题:R语言基础(一):数据结构篇

    本文链接:https://www.haomeiwen.com/subject/cvbnattx.html