R语言入门09:因子、列表、矩阵、数组

文摘   2024-11-04 19:03   广东  



为了方便大家学习,我已经录制了配套的视频,放在了哔哩哔哩(我的B站账号:阿越就是我),免费观看,复制以下网址粘贴到浏览器打开即可:https://space.bilibili.com/42460432/channel/collectiondetail?sid=3740949


本期目录:

  • 因子

    • 创建因子

    • 因子水平和标签

    • 计数

  • 矩阵

  • 数组

  • 列表

    • 创建列表

    • 列表取子集

    • 修改名字

    • 添加/删除列表元素

    • 列表展开


今天继续介绍R语言中的数据结构:因子、列表、矩阵、数组

因子

多数变量可归为名义型、有序型或连续型变量。

名义型变量(nominal-variable)是没有顺序之分的类别变量。糖尿病类型diabetesType1Type2)是名义型变量的一例。即使在数据中Type1编码为1Type2编码为2`,这也并不意味着二者是有序的。

有序型变量(ordinal-variable)表示一种顺序关系,而非数量关系。病情statuspoorimprovedexcellent)是有序型变量的一个示例。很明显病情为poor(较差)病人的状态不如improved(病情好转)的病人,但并不知道相差多少。

连续型变量(continuous-variable)可以呈现为某个范围内的任意值,并同时表示了顺序和数量。年龄Age就是一个连续型变量,它能够表示像14.5或22.8这样的值以及其间的其他任意值。

类别(名义型)变量和有序类别(有序型)变量在R中称为因子(factor)。因子在R中非常重要,因为它决定了数据的分析方式以及如何进行视觉呈现。

创建因子

因子可以通过函数factor()创建。比如用以下代码即可创建一个名为status的因子型向量:

status <- factor(c("Poor""Improved""Excellent""Poor"))
status
## [1] Poor      Improved  Excellent Poor     
## Levels: Excellent Improved Poor

此时的status是一个因子型向量,也是没有顺序之分的名义型变量,虽然给出了Levels,但是并不能表示它们之间有高低顺序,默认的水平顺序是按照首字母排列的。

因子水平和标签

如果要更改不同水平的顺序,可以使用以下代码:

# 指定顺序
levels(status) <- c("Poor""Excellent""Improved")
status
## [1] Improved  Excellent Poor      Improved 
## Levels: Poor Excellent Improved

或者直接在factor()中指定:

status <- factor(c("Poor""Improved""Excellent""Poor"),
                 levels = c("Poor""Excellent""Improved")
                 )
status
## [1] Poor      Improved  Excellent Poor     
## Levels: Poor Excellent Improved

对于不同的水平,你也可以修改它的显示标签:

status <- factor(c("Poor""Improved""Excellent""Poor"),
                 levels = c("Poor""Excellent""Improved"),
                 labels = c("第一水平""第二水平""第三水平")
                 )
status
## [1] 第一水平 第三水平 第二水平 第一水平
## Levels: 第一水平 第二水平 第三水平

如果想要把某个变量变成有序型变量,可以使用ordered=TRUE参数:

status <- factor(c("Poor""Improved""Excellent""Poor"),
                 ordered = T
                 )
status
## [1] Poor      Improved  Excellent Poor     
## Levels: Excellent < Improved < Poor

可以看到此时结果中的Levels有了小于号,用来表示高低顺序。

Note

名义型变量和有序型变量在进行统计分析时会使用完全不同的方法,比如在进行线性回归或者cox回归分析时,名义型变量的默认方法是哑变量编码,而有序型变量的编码方式是正交多项式编码。相关内容可参考:分类变量进行回归分析时的编码方案

计数

table()函数可用于查看每个水平的数量:

table(status)
## status
## Excellent  Improved      Poor 
##         1         1         2

如果和length()同用则可以快速计算有几个水平(或类别,在分类变量中很常用):

# 查看有几个类别
length(table(status))
## [1] 3

因子类型是R语言中处理分类变量非常有用的类型,在画图的时候也可以使用因子规定好顺序,方便对图形进行排列。

forcats包提供了一套专门用于处理因子的函数,非常实用,大家可以阅读以下文章进一步了解:

矩阵

矩阵,matrix,表面看起来像一个数据框,有行和列,也是二维的,但是矩阵里面的所有元素都必须是同一类型的,比如必须都是数值型,或者必须都是字符型,或者必须都是逻辑型,等。

可通过函数matrix()创建矩阵。一般使用格式为:

myymatrix <- matrix(vector, nrow = 多少行?, ncol = 多少列?,
                    byrow = 是不是按行进行填充?,
                    dimnames = list(行名, 列名))

其中vector是矩阵所需要的元素,nrowncol用以指定行和列的数量,dimnames包含了以字符型向量表示的行名和列名(这个参数可以省略不写)。选项byrow则表明矩阵应当按行填充(byrow=TRUE)还是按列填充(byrow=FALSE),默认情况下按列填充。

以下代码创建了一个5行、4列的矩阵,用1~20这20个数字进行填充,并且定义了行的名字和列的名字,并且是按列进行填充:

y <- matrix(1:20, nrow=5, ncol=4,
            dimnames = list(c("行1","行2","行3","行4","行5"),
                            c("列1","列2","列3","列4"))
            ) 
y
##     列1 列2 列3 列4
## 行1   1   6  11  16
## 行2   2   7  12  17
## 行3   3   8  13  18
## 行4   4   9  14  19
## 行5   5  10  15  20

对矩阵取行和列的语法和数据框完全一样,使用方括号即可,这里就不重复了。

y[1,2]
## [1] 6

数组

数组,array,类似矩阵,但可以有更多的维度(行、列以外的方向),比如可以有3维甚至更多,这种结构可能是你无法想象的(超过3维的东西你能想象出来吗?),但是幸好这个结构我们用的不多。

数组可通过array函数创建,形式如下:

myarray <- array(vector, dimensions, dimnames)

其中vector包含了数组中的数据,dimensions是一个数值型向量,给出了各个维度下标的最大值,而dimnames是可选的、各维度名称标签的列表。

以下代码创建一个三维数组(234):

dim1 <- c("A1""A2")
dim2 <- c("B1""B2""B3")
dim3 <- c("C1""C2""C3""C4")

z <- array(1:24, c(234), 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
## 
## , , C3
## 
##    B1 B2 B3
## A1 13 15 17
## A2 14 16 18
## 
## , , C4
## 
##    B1 B2 B3
## A1 19 21 23
## A2 20 22 24

列表

列表,list,是除了数据框之外第二重要的数据结构,甚至可以说是最重要的数据结构,但同时也是最复杂的一种结构。

列表是一个大型的存储结构,里面啥都能放。比如,可以包含不同类型的数据,也可以包含其他数据结构,如向量、矩阵或数据框等,列表中也可以包含列表。

创建列表

可以使用函数list()创建列表,使用语法为:

mylist <- list(object1, object2, ...)

其中的对象可以是目前为止讲到的任何结构。你还可以为列表中的对象命名:

mylist <- list(name1=object1, name2=object2, ...)

以下是一个创建列表的示例,我们先创建了5个不同类型的对象,然后把这些对象全部放到1个列表中:

g <- "My First List" # 字符串
h <- c(25261839# 数值型向量
j <- matrix(1:10, nrow=5# 矩阵
k <- c("one""two""three"# 字符型向量
l <- list("apple",1,TRUE# 列表

# 放到1个列表中
mylist <- list(title=g, ages=h, j, k, l)
mylist
## $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"
## 
## [[5]]
## [[5]][[1]]
## [1] "apple"
## 
## [[5]][[2]]
## [1] 1
## 
## [[5]][[3]]
## [1] TRUE

可以看出列表的成分非常复杂,上面的列表mylist的长度为5,因为有5个成分:

# 查看长度
length(mylist)
## [1] 5

前两个成分是有名字的:titleages,后三个成分没有名字,但是有序号,分别是[[3]][[4]][[5]]

列表取子集

如果你要提取列表中的成分(或者叫对列表取子集),可以直接使用序号或者名字:

mylist[2# 取第2个成分
## $ages
## [1] 25 26 18 39
mylist["title"# 取第一个成分
## $title
## [1] "My First List"

注意此时得到的对象仍然是list

class(mylist[2])
## [1] "list"
class(mylist["title"])
## [1] "list"

列表中还有一个特殊的操作,也就是[[]],两个中括号,这样可以直接提取到具体的内容:

# 直接提取具体的内容
mylist[["title"]]
## [1] "My First List"

# 此时得到的是字符型向量
class(mylist[["title"]])
## [1] "character"

或者可以使用$,也可以直接得到具体的内容,但是这种方法只能用于有名字的时候:

mylist$title
## [1] "My First List"

如果使用了[[]]或者$符号取子集后,得到的是具体的内容,我们可以继续通过[]选择其中的元素:

# 取第2个对象中的第1个元素
mylist[[2]][1]
## [1] 25

修改名字

如果要给列表中的成分添加/修改/删除名字,也是使用names()

# 给第3-5个对象添加名字
names(mylist)[3:5] <- c("名字3","名字4","名字5")

# 或者:
names(mylist)[c(3:5)] <- c("名字3","名字4","名字5")

# 查看结果
names(mylist)
## [1] "title" "ages"  "名字3" "名字4" "名字5"
#修改第一个成分的名字:
names(mylist)[1] <- "改个名字"
names(mylist)
## [1] "改个名字" "ages"     "名字3"    "名字4"    "名字5"

删除名字:

# 删除所有名字
names(mylist) <- NULL
names(mylist) # 此时再查看名字已经没有了
## NULL

添加/删除列表元素

如果要向列表中添加新的成分:

mylist[["新的元素"]] <- c(1,2,3)
mylist
## [[1]]
## [1] "My First List"
## 
## [[2]]
## [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"
## 
## [[5]]
## [[5]][[1]]
## [1] "apple"
## 
## [[5]][[2]]
## [1] 1
## 
## [[5]][[3]]
## [1] TRUE
## 
## 
## $新的元素
## [1] 1 2 3

删除列表中的成分:

# 删除第一个成分
mylist <- mylist[-1]
mylist
## [[1]]
## [1] 25 26 18 39
## 
## [[2]]
##      [,1] [,2]
## [1,]    1    6
## [2,]    2    7
## [3,]    3    8
## [4,]    4    9
## [5,]    5   10
## 
## [[3]]
## [1] "one"   "two"   "three"
## 
## [[4]]
## [[4]][[1]]
## [1] "apple"
## 
## [[4]][[2]]
## [1] 1
## 
## [[4]][[3]]
## [1] TRUE
## 
## 
## $新的元素
## [1] 1 2 3

# 或者
mylist$新的元素 <- NULL
mylist
## [[1]]
## [1] 25 26 18 39
## 
## [[2]]
##      [,1] [,2]
## [1,]    1    6
## [2,]    2    7
## [3,]    3    8
## [4,]    4    9
## [5,]    5   10
## 
## [[3]]
## [1] "one"   "two"   "three"
## 
## [[4]]
## [[4]][[1]]
## [1] "apple"
## 
## [[4]][[2]]
## [1] 1
## 
## [[4]][[3]]
## [1] TRUE

列表展开

把列表展开成向量:

unlist(mylist)
##                                                                                 
##    "25"    "26"    "18"    "39"     "1"     "2"     "3"     "4"     "5"     "6" 
##                                                                                 
##     "7"     "8"     "9"    "10"   "one"   "two" "three" "apple"     "1"  "TRUE"
class(unlist(mylist))
## [1] "character"
str(unlist(mylist)) # 命名字符型向量
##  Named chr [1:20] "25" "26" "18" "39" "1" "2" "3" "4" "5" "6" "7" "8" "9" ...
##  - attr(*, "names")= chr [1:20] "" "" "" "" ...

掌握了这些基本的数据结构和常用操作后,就算是正式入门R语言了,后面的章节会继续一些常用的数据处理操作。



联系我们,关注我们

  1. 免费QQ交流群1:613637742
  2. 免费QQ交流群2:608720452
  3. 公众号消息界面关于作者获取联系方式
  4. 知乎、CSDN、简书同名账号
  5. 哔哩哔哩:阿越就是我

生信菜鸟团
生信菜鸟团荣誉归来,让所有想分析生物信息学数据的小伙伴找到归属,你值得拥有!
 最新文章