注:根据张敬信老师的《R语言编程—基于tidyverse》一书,所作笔记。
第一章 基础语法
本章将学习R 语言基本语法,也是与其他编程语言相通的部分,包括:搭建R 环境、常用数据类型(数据结构)、控制结构(分支、循环)、自定义函数。
1.1 搭建R 环境及常用操作
1.1.1 搭建R 环境
- 安装R
从R语言的官网The R Project for Statistical Computing下载R安装包,根据自己的操作系统,下载相应的最新版安装即可。linux推荐conda安装,可以管理不同的R版本,更好处理依赖关系。 - 安装RStudio
从RStudio官网下载安装RStudio: 桌面版,服务器版。
1.1.2 常用操作
- 安装包
扩展包(package),简称包。通常R 包都来自CRAN,审核比较规范严格,包的质量相对更有保障。建议使用命令安装:
install.packages("openxlsx")
Github 也是R 包的较大的来源,有些作者自己开发的R 包只放在Github,也有很多CRAN R 包的最新开发版都位于Github. 可以先安装devtools 或remotes 包,再用其install_github() 安装Github 来源的包:
devtools::install_github("tidyverse/dplyr") # 或者
remotes::install_github("tidyverse/dplyr")
若网络等原因,导致直接从Github 安装包失败,也可以将整个包文件夹从网页下载下来,解压缩到当前路径(或提供完整路径),再从本地安装它:
install.packages("dplyr-master", repos=NULL, type="source")
另外,生信领域在R 中自成一派,有专门的包的大本营:bioconductor,先安装BiocManager 包,再用install() 函数安装bioconductor 来源的包:
BiocManager::install("openxlsx")
- 加载包
library(openxlsx)
- 更新包
update.packages("openxlsx")
update.packages() # 更新所有包
- 删除包
remove.packages("openxlsx")
- 获取或设置当前路径
getwd()
setwd("D:/R-4.1.1/tests")
- 赋值
R 标准语法中赋值不是用= ,而是<- 或->
x <- 1:10
x + 2
#[1] 3 4 5 6 7 8 9 10 11 12
R 也允许用= 赋值,建议用更现代和简洁的= 赋值。 - 基本运算
数学运算:
+ - * /、^ (求幂) 、%% (按模求余1) 、%/% (整除)
比较运算:
>、<、>=、<=、==、!=
identical(x,y)—— 判断两个对象是否严格相等;
all.equal(x,y) 或dplyr::near(x,y)——判断两个浮点数是否近似相等(误差1.5e−8)
0L == 0
## [1] TRUE
identical(0L, 0)
## [1] FALSE
sqrt(2)^2 == 2
## [1] FALSE
identical(sqrt(2)^2, 2)
## [1] FALSE
all.equal(sqrt(2)^2, 2)
## [1] TRUE
dplyr::near(sqrt(2)^2, 2)
## [1] TRUE
逻辑运算:
| (或) , & (与) ,! (非) ,xor() (异或)
&& 和|| 是短路运算,即遇到TRUE (FALSE) 则返回TRUE (FALSE) 而不继续往下计算;而& 和| 是向量运算符,对向量中所有元素分别进行运算。
- 基本数据类型
R 中的基本数据类型包括:
numeric——数值型,又分为integer (整数型) 和double (浮点型)
logical——逻辑型,只有TRUE 和FALSE,或T 和F
character——字符型,引号括起来的若干字符
R 中用NA 表示缺失值,NULL 表示空值,NaN 表示非数,Inf 表示无穷大
对于R 中大多数函数,NA 具有传染性,即NA 参与的运算,结果会变成NA
R 中注释一行代码用#
可用函数class(x) / typeof(x) / mode(x) 查看对象x 的类型
在展现数据的细节上,mode() < class() < typeof()
str(x) 显示对象x 的结构
- 保存和载入数据
save(x, file = "datas/dat.Rda")
load("datas/dat.Rda")
- 清屏和清除内存变量
Ctrl + L 或单击命令窗口右上角的小刷子可对命令窗口清屏。
若要清除当前变量,用:
rm(x) # 清除变量x
rm(list = ls(all = TRUE)) # 清除所有当前变量
注:单击Environment 窗口的小刷子也是清除所有当前变量。 - 获取帮助
编程语言最好的学习资料就是帮助。
函数帮助
命令窗口执行:?plot
?plot - R Script 与R Project
R 脚本是单个可执行的R 代码文件,后缀名为.R,单击New File 按钮,选择R Script,或使用快捷键Ctrl + Shift + N, 则新建R 脚本。
R 脚本中都是可执行的R 代码+ 注释,选中部分代码,点击Run 运行选中的代码。
R 项目(Project)是完成某个项目或任务的一系列文件的合集(文件夹) ,包括数据文件、若干R脚本及其他附件,其中包含一个*.Rproj 文件;
强烈建议使用R 项目,它能方便系统地管理服务于共同目的一系列的文件,可以方便移动位置甚至是移到其他电脑,而不需要做任何路径设置就能成功运行。 - Rmarkdown
后缀名为.Rmd 的交互式文档,是markdown 语法与R 脚本的结合,可以将可执行R 代码和不可执行的文字叙述,融为一个文件。
1.2 数据结构I:向量、矩阵、多维数组
数据结构是为了便于存储不同类型的数据而设计的数据容器。
R 中常用的数据结构可划分为:
同质数据类型(homogeneous) ,即所存储的一定是相同类型的元素,包括向量、矩阵、多维数组;
异质数据类型(heterogeneous) ,即可以存储不同类型的元素,这大大提高了存储的灵活性,但同时也降低了存储效率和运行效率,包括列表、数据框。
另外,还有字符串、日期时间数据、时间序列数据、空间地理数据等。
向量都有两个属性:type (类型) 、length (长度) ;还能以属性的方式向向量中任意添加额外的metadata (元数据) ,属性可用来创建扩展向量,以执行一些新的操作。常用的扩展向量有:
- 基于整数型向量构建的因子
- 基于数值型向量构建的日期和日期时间
- 基于数值型向量构建的时间序列
- 基于列表构建的数据框和tibble
1.2.1 向量(一维数据)
向量是由一组相同类型的原始值构成的序列,可以是一组数值、一组逻辑值、一组字符串等。
常用的向量有:数值向量、逻辑向量、字符向量。
- 数值向量
数值向量就是由数值组成的向量,单个数值是长度为1 的数值向量
x = 1.5
x
## [1] 1.5
可以用numeric() 来创建一个全为0 的指定长度的数值向量:
numeric(10)
## [1] 0 0 0 0 0 0 0 0 0 0
R 中经常用函数c() 实现将多个对象合并到一起:
c(1, 2, 3, 4, 5)
## [1] 1 2 3 4 5
c(1, 2, c(3, 4, 5)) # 将多个数值向量合并成一个数值向量
## [1] 1 2 3 4 5
创建等差的数值向量,用: 或者函数seq() ,基本格式为:
seq(from, to, by, length.out, along.with, ...)
from:设置首项(默认为1) ;
to:设置尾项;
by:设置等差值(默认为1 或-1) ;
length.out:设置序列长度;
along.with:以该参数的长度作为序列长度。
1:5 # 同seq(5) 或seq(1,5)
## [1] 1 2 3 4 5
seq(1, 10, 2) # 从1 开始, 到10 结束, 步长为2
## [1] 1 3 5 7 9
seq(3, length.out=10)
## [1] 3 4 5 6 7 8 9 10 11 12
创建重复的数值向量用函数rep(),基本格式为:
rep(x, times,length.out, each, ...)
x:为要重复的序列;
times:设置序列重复次数;
length.out:设置产生的序列的长度;
each:设置每个元素分别重复的次数(默认为1) 。
x = 1:3
rep(x, 2)
## [1] 1 2 3 1 2 3
rep(x, each = 2)
## [1] 1 1 2 2 3 3
rep(x, c(2, 1, 2)) # 按照规则重复序列中的各元素
## [1] 1 1 2 3 3
rep(x, each = 2, length.out = 4)
## [1] 1 1 2 2
rep(x, each = 2, times = 3)
## [1] 1 1 2 2 3 3 1 1 2 2 3 3 1 1 2 2 3 3
- 逻辑向量
逻辑向量,是一组逻辑值(TRUE 或FALSE, 或简写为T 或F) 的向量。
c(1, 2) > c(2, 1) # 等价于c(1 > 2, 2 > 1)
## [1] FALSE TRUE
c(2, 3) > c(1, 2, -1, 3) # 等价于c(2 > 1, 3 > 2, 2 > -1, 3 > 3)
## [1] TRUE TRUE TRUE FALSE
除了比较运算符外,还可以用%in% 判断元素是否属于集合:
c(1, 4) %in% c(1, 2, 3) # 左边向量每一个元素是否属于右边集合
## [1] TRUE FALSE
- 字符向量
字符(串) 向量,是一组字符串组成的向量,R 中单引号和双引号都可以用来生成字符向量。
"hello, world!"
## [1] "hello, world!"
c("Hello", "World")
## [1] "Hello" "World"
c("Hello", "World") == "Hello, World"
## [1] FALSE FALSE
- 访问向量子集
即访问向量的一些特定元素或者某个子集。注意,R 中的索引是从1 开始的。
使用元素的位置来访问:
v1 = c(1, 2, 3, 4)
v1[2] # 第2 个元素
v1[2:4] # 第2-4 个元素
v1[-3] # 除了第3 个之外的元素
也可以放任意位置的数值向量,但是注意不能既放正数又放负数:
v1[c(1,3)]
v1[c(1, 2, -3)] # 报错
访问不存在的位置也是可以的,返回NA:
v1[3:6]
使用逻辑向量来访问,输入与向量相同长度的逻辑向量,以此决定每一个元素是否要被获取:
v1[c(TRUE, FALSE, TRUE, FALSE)]
这可以引申为‘‘根据条件访问向量子集’’:
v1[v1 <= 2] # 同v1[which(v1 <= 2)] 或subset(v1, v1<=2)
v1[v1 ^ 2 - v1 >= 2]
which.max(v1) # 返回向量v1 中最大值所在的位置
which.min(v1) # 返回向量v1 中最小值所在的位置
- 对向量子集赋值,替换相应元素
对向量子集赋值,就是先访问到向量子集,再赋值。
v1[2] = 0
v1[2:4] = c(0, 1, 3)
v1[c(TRUE, FALSE, TRUE, FALSE)] = c(3, 2)
v1[v1 <= 2] = 0
注意,若对不存在的位置赋值,前面将用NA 补齐。
- 对向量元素命名
可以在创建向量的同时对其每个元素命名:
x = c(a = 1, b = 2, c = 3)
x
## a b c
## 1 2 3
命名后,就可以通过名字来访问向量元素:
x[c("a", "c")]
x[c("a", "a", "c")] # 重复访问也是可以的
x["d"] # 访问不存在的名字
获取向量元素的名字:
names(x)
## [1] "a" "b" "c"
更改向量元素的名字:
names(x) = c("x", "y", "z")
x["z"]
## z
## 3
移除向量元素的名字:
names(x) = NULL
x
## [1] 1 2 3
- 对向量排序
向量排序函数sort(),基本格式为:
sort(x, decreasing, na.last, ...)
x:为排序对象(数值型或字符型) ;
decreasing:默认为FALSE 即升序,TRUE 为降序;
na.last:默认为FALSE,若为TRUE,则将向量中的NA 值放到序列末尾。
函数order(), 返回元素排好序的索引,以其结果作为索引访问元素,正好是排好序的向量。
函数rank(),返回值是该向量中对应元素的‘‘排名’’。
x = c(1,5,8,2,9,7,4)
sort(x)
## [1] 1 2 4 5 7 8 9
order(x) # 默认升序,排名第2 的元素在原向量的第4 个位置
## [1] 1 4 7 2 6 3 5
x[order(x)] # 同sort(x)
## [1] 1 2 4 5 7 8 9
rank(x) # 默认升序,第2 个元素排名第4 位
## [1] 1 4 6 2 7 5 3
1.2.2 矩阵(二维数据)
矩阵是一个用两个维度表示和访问的向量。因此,适用于向量的性质和方法大多也适用于矩阵:矩阵也要求元素是同一类型,数值矩阵、逻辑矩阵等。
- 创建矩阵
函数matrix() 将一个向量创建为矩阵,其基本格式为:
matrix(x, nrow, ncol, byrow, dimnames, ...)
x:为数据向量作为矩阵的元素;
nrow:设定行数;
ncol:设定列数;
byrow:设置是否按行填充,默认为FALSE (按列填充) ;
dimnames:用字符型向量表示矩阵的行名和列名。
matrix(c(1, 2, 3,
4, 5, 6,
7, 8, 9), nrow = 3, byrow = FALSE)
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
matrix(c(1, 2, 3,
4, 5, 6,
7, 8, 9), nrow = 3, byrow = TRUE)
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 4 5 6
## [3,] 7 8 9
#对矩阵的行列命名:
matrix(1:9, nrow = 3, byrow = TRUE,
dimnames = list(c("r1","r2","r3"), c("c1","c2","c3")))
## c1 c2 c3
## r1 1 2 3
## r2 4 5 6
## r3 7 8 9
#也可以创建后再命名:
m1 = matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), ncol = 3)
rownames(m1) = c("r1", "r2", "r3")
colnames(m1) = c("c1", "c2", "c3")
- 访问矩阵子集
矩阵是用两个维度表示和访问的向量,可以用一个二维存取器[ , ] 来访问,这类似于构建向量子集时用的一维存取器[]。可以为每个维度提供一个向量来确定一个矩阵的子集。方括号中的第1 个参数是行选择器,第2个参数是列选择器。与构建向量子集一样,可以在两个维度中使用数值向量、逻辑向量和字符向量。
m1[1,2] # 提取第1 行,第2 列的单个元素
m1[1:2, 2:4] # 提取第1 至2 行,第2 至4 列的元素
m1[c("r1","r3"), c("c1","c3")] # 提取行名为r1 和r3,列名为c1 和c3 的元素
若一个维度空缺,则选出该维度的所有元素:
m1[1,] # 提取第1 行,所有列元素
m1[,2:4] # 提取所有行,第2 至4 列的元素
负数表示在构建矩阵子集时可排除该位置,这和向量中的用法一致:
m1[-1,] # 提取除了第1 行之外的所有元素
m1[,-c(2,4)] # 提取除了第2 和4 列之外的所有元素
注意,矩阵是一个用两个维度表示和访问的向量,但它本质上仍然是一个向量。因此,向量的一
维存取器也可以用来构建矩阵子集:
m1[3:7]
## [1] 3 4 5 6 7
由于向量只包含相同类型的元素,矩阵也是如此。所以它们的操作方式也相似。若输入一个不等
式,则返回同样大小的逻辑矩阵:
m1 > 3
## c1 c2 c3
## r1 FALSE TRUE TRUE
## r2 FALSE TRUE TRUE
## r3 FALSE TRUE TRUE
根据它就可以选择矩阵元素或赋值:
m1[m1 > 3] # 注意选出来的结果是向量
## [1] 4 5 6 7 8 9
1.2.3 多维数组(多维数据)
向量/矩阵向更高维度的自然推广。具体来说,多维数组就是一个维度更高(通常大于2) 、可访问的向量。数组也要求元素是同一类型。
- 创建多维数组
函数array() 将一个向量创建为多维数组,基本格式为:
array(x, dim, dimnames, ...)
x:为数据向量作为多维数组的元素;
dim:设置多维数组各维度的维数;
dimnames:设置多维数组各维度的名称。
a1 = array(1:24, dim = c(3, 4, 2))
a1
## , , 1
##
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
##
## , , 2
##
## [,1] [,2] [,3] [,4]
## [1,] 13 16 19 22
## [2,] 14 17 20 23
## [3,] 15 18 21 24
也可以在创建数组时对每个维度进行命名:
a1 = array(1:24, dim = c(3, 4, 2),dimnames=list(c("r1","r2","r3"),c("c1","c2","c3","c4"), c("k1","k2")))
或者创建之后再命名
a1 = array(1:24, dim = c(3, 4, 2))
dimnames(a1) = list(c("r1","r2","r3"),c("c1","c2","c3","c4"), c("k1","k2"))
- 访问多维数组子集
第3 个维度姑且称为‘‘页”
a1[2,4,2] # 提取第2 行, 第4 列, 第2 页的元素
a1["r2","c4","k2"] # 提取第r2 行, 第c4 列, 第k2 页的元素
a1[1,2:4,1:2] # 提取第1 行, 第2 至4 列, 第1 至2 页的元素
a1[,,2] # 提取第2 页的所有元素
dim(a1) # 返回多维数组a1 的各维度的维数
1.3 数据结构II:列表、数据框、因子
1.3.1 列表(list)
列表,可以包含不同类型的对象,甚至可以包括其他列表。列表最大的好处就是,它能够将多个不同类型的对象打包到一起,使得可以根据位置和名字访问它们。
- 创建列表
可以用函数list() 创建列表。不同类型的对象可以放入同一个列表中。
l0 = list(1, c(TRUE, FALSE), c("a", "b", "c"))
l0
## [[1]]
## [1] 1
##
## [[2]]
## [1] TRUE FALSE
##
## [[3]]
## [1] "a" "b" "c"
可以在创建列表时,为列表的每个成分指定名字:
l1 = list(A = 1, B = c(TRUE, FALSE), C = c("a", "b", "c"))
l1
## $A
## [1] 1
##
## $B
## [1] TRUE FALSE
##
## $C
## [1] "a" "b" "c"
也可以创建列表后再对列表成分命名或修改名字:
names(l1) = NULL # 移除列表成分的名字
names(l1) = c("x","y","z")
- 从列表中提取成分的内容
提取列表中成分下的内容,最常用的方法是用$,通过成分名字来提取该成分下的内容:
l1$y
l1$m # 访问不存在的成分m, 将会返回NULL
也可以用[[n]] 来提取列表第n 个成分的内容,n 也可以换成成分的名字:
l1[[2]] # 同l1[["y"]]
用[[]] 提取列表中某个成分的内容更加灵活,可用在函数调用中,通过参数来传递成分名字:
p = "y" # 想要提取其内容的成分名字
l1[[p]]
- 提取列表子集
经常也需要从列表中提取多个成分及其内容,由这些成分组成的列表构成了原列表的一个子集。就像提取向量和矩阵的子集一样,提取一个列表子集是用[],可以取出列表中的一些成分,作为一个新的列表。[] 中可以用字符向量表示成分名字,用数值向量表示成分位置,或用逻辑向量指定是否选择,来取出列表成分。
l1["x"] # 同l1[1]
l1[c("x", "z")] # 同l1[c(1, 3)], l1[c(TRUE, FALSE, TRUE)]
用[] 提取若干成分时,返回列表的子集,还是一个列表;用[[ ]] 提取单个成分的元素,返回的是对应成分的元素。总之,[] 提取对象的子集,类型仍是该对象;[[]] 提取对象的内容(下一级元素) 。
- 对列表的成分赋值
即先访问(提取) 到列表的成分,再赋以相应的值。注意,若给一个不存在的成分赋值,列表会自动地在对应名称或位置下增加一个新成分。
l1$x = 0 # 将列表的成分x 赋值为0
也可以同时给多个列表成分赋值:
l1[c("x", "y")] = list(x = "new value for y", y = c(3, 1))
若要移除列表中的某些成分,只需赋值为NULL:
l1[c("z", "m")] = NULL
- 列表函数
用函数as.list() 可将向量转换成列表:
l2 = as.list(c(a = 1, b = 2))
l2
## $a
## [1] 1
##
## $b
## [1] 2
用去列表化函数unlist(),可将一个列表打破成分界线,强制转换成一个向量:
unlist(l2)
## a b
## 1 2
tidyverse 系列中的purrr 包为方便操作列表,提供了一系列列表相关的函数,建议读者查阅使
用:
pluck():同[[ 提取列表中的元素
keep(): 保留满足条件的元素
discard(): 删除满足条件的元素
compact(): 删除列表中的空元素
append():在列表末尾增加元素
flatten(): 摊平列表(只摊平一层)
1.3.2 数据框(数据表)
数据框是由列向量组成、有着矩阵形式的列表。数据框与最常见的数据表是一致的:每一列代表一个变量属性,每一行代表一条样本数据。R 中自带的数据框是data.frame,建议改用更现代的数据框:tibble。
- 创建数据框
用tibble() 根据若干列向量创建tibble:
library(tidyverse) # 或tibble
persons = tibble(
Name = c("Ken", "Ashley", "Jennifer"),
Gender = c("Male", "Female", "Female"),
Age = c(24, 25, 23),
Major = c("Finance", "Statistics", "Computer Science"))
persons
## # A tibble: 3 x 4
## Name Gender Age Major
## <chr> <chr> <dbl> <chr>
## 1 Ken Male 24 Finance
## 2 Ashley Female 25 Statistics
## 3 Jennifer Female 23 Computer Science
用tribble() 按行录入数据式创建tibble:
tribble(
~Name, ~Gender, ~Age, ~Major,
"Ken", "Male", 24, "Finance",
"Ashley", "Female", 25, "Statistics",
"Jennifer", "Female", 23, "Computer Science")
用as_tibble() 将data.frame, matrix, 各成分等长度的list, 转换为tibble。
对于不等长的列表转化为数据框:
a = list(A = c(1, 3, 4), B = letters[1:4])
a
## $A
## [1] 1 3 4
##
## $B
## [1] "a" "b" "c" "d"
# lengths() 获取list 中每个元的长度
map_dfc(a, `length<-`, max(lengths(a))) # map 循环参阅1.6.2 节
## # A tibble: 4 x 2
## A B
## <dbl> <chr>
## 1 1 a
## 2 3 b
## 3 4 c
## 4 NA d
df = tibble(id = 1:4,
level = c(0, 2, 1, -1),
score = c(0.5, 0.2, 0.1, 0.5))
names(df) = c("id", "x", "y")
df
## # A tibble: 4 x 3
## id x y
## <int> <dbl> <dbl>
## 1 1 0 0.5
## 2 2 2 0.2
## 3 3 1 0.1
## 4 4 -1 0.5
数据框既是列表的特例,也是矩阵的推广,因此访问这两类对象的方式都适用于数据框。
- 提取数据框的元素、子集
(1) 以列表方式提取数据框的元素、子集
可以用$ 按列名来提取某一列的值,或者用[[]] 按照位置或列名提取。例如,提取列名为x 列的值,得到向量:
df$x # 同df[["x"]], df[[2]]
## [1] 0 2 1 -1
以列表形式构建子集完全适用于数据框,同时也会生成一个新的数据框。提取子集的操作符[] 允许用数值向量表示列的位置,用字符向量表示列名,或用逻辑向量指定是否选择。
例如,提取数据框的一列或多列,得到子数据框:
df[1] # 提取第1 列, 同df["id"]
## # A tibble: 4 x 1
## id
## <int>
## 1 1
## 2 2
## 3 3
## 4 4
df[1:2] # 同df[c("id","x")], df[c(TRUE,TRUE,FALSE)]
## # A tibble: 4 x 2
## id x
## <int> <dbl>
## 1 1 0
## 2 2 2
## 3 3 1
## 4 4 -1
(2) 以矩阵方式提取数据框的元素、子集
以列表形式操作并不支持行选择。以矩阵形式操作更加灵活,若将数据框看作矩阵,其二维形式 的存取器可以很容易地获取一个子集的元素,同时支持列选择和行选择。换句话说,可以使用[i, j] 指定行或列来提取数据框子集,[ , ] 内可以是数值向量、字符向量或者逻辑向量。
若行选择器为空,则只选择列(所有行) :
df[, "x"]
## # A tibble: 4 x 1
## x
## <dbl>
## 1 0
## 2 2
## 3 1
## 4 -1
df[, c("x","y")] # 同df[,2:3]
## # A tibble: 4 x 2
## x y
## <dbl> <dbl>
## 1 0 0.5
## 2 2 0.2
## 3 1 0.1
## 4 -1 0.5
若列选择器为空,则只选择行(所有列) :
df[c(1,3),]
## # A tibble: 2 x 3
## id x y
## <int> <dbl> <dbl>
## 1 1 0 0.5
## 2 3 1 0.1
同时选择行和列:
df[1:3, c("id","y")]
## # A tibble: 3 x 2
## id y
## <int> <dbl>
## 1 1 0.5
## 2 2 0.2
## 3 3 0.1
根据条件筛选数据。例如用y >= 0.5 筛选df 的行,并选择id 和y 两列:
df[df$y >= 0.5, c("id","y")]
## # A tibble: 2 x 2
## id y
## <int> <dbl>
## 1 1 0.5
## 2 4 0.5
按列名属于集合{x, y, w} 来筛选df 的列,并选择前两行:
ind = names(df) %in% c("x","y","w")
df[1:2, ind]
## # A tibble: 2 x 2
## x y
## <dbl> <dbl>
## 1 0 0.5
## 2 2 0.2
- 给数据框赋值
给数据框赋值,就是选择要赋值的位置,再准备好同样大小且格式匹配的数据,赋值给那些位置即可,所以同样有列表方式和矩阵方式。
(1) 以列表方式给数据框赋值
用$ 或[[ ]] 对数据框的1 列赋值
df$y = c(0.6,0.3,0.2,0.4) # 同df[["y"]] = c(0.6,0.3,0.2,0.4)
利用现有列,创建(计算) 新列:
df$z = df$x + df$y
df
## # A tibble: 4 x 4
## id x y z
## <int> <dbl> <dbl> <dbl>
## 1 1 0 0.5 0.5
## 2 2 2 0.2 2.2
## 3 3 1 0.1 1.1
## 4 4 -1 0.5 -0.5
df$z = as.character(df$z) # 转换列的类型
df
## # A tibble: 4 x 4
## id x y z
## <int> <dbl> <dbl> <chr>
## 1 1 0 0.5 0.5
## 2 2 2 0.2 2.2
## 3 3 1 0.1 1.1
## 4 4 -1 0.5 -0.5
用[] 可以对数据框的1 列或多列进行赋值:
df["y"] = c(0.8,0.5,0.2,0.4)
df[c("x", "y")] = list(level = c(1,2,1,0),
score = c(0.1,0.2,0.3,0.4))
(2) 以矩阵方式给数据框赋值
以列表方式对数据框进行赋值时,也是只能访问列。若需要更加灵活地进行赋值操作,可以以矩阵方式进行。
df[1:3,"y"] = c(-1,0,1)
df[1:2,c("x","y")] = list(level = c(0,0),score = c(0.9,1.0))
- 一些有用函数
函数str() 或glimpse() 作用在R 对象上,显示该对象的结构:
str(persons)
## tibble [3 x 4] (S3: tbl_df/tbl/data.frame)
## $ Name : chr [1:3] "Ken" "Ashley" "Jennifer"
## $ Gender: chr [1:3] "Male" "Female" "Female"
## $ Age : num [1:3] 24 25 23
## $ Major : chr [1:3] "Finance" "Statistics" "Computer Science"
summary() 作用在数据框/列表上,将生成各列/成分的汇总信息:
summary(persons)
## Name Gender Age
## Length:3 Length:3 Min. :23.0
## Class :character Class :character 1st Qu.:23.5
## Mode :character Mode :character Median :24.0
## Mean :24.0
## 3rd Qu.:24.5
## Max. :25.0
## Major
## Length:3
## Class :character
## Mode :character
经常需要将多个数据框(或矩阵) 按行或按列进行合并。用函数rbind(),增加行(样本数据) ,要求宽度(列数) 相同;用函数cbind(),增加列(属性变量) ,要求高度(行数) 相同。
例如,向数据框persons 数据框中添加一个人的新记录:
rbind(persons,
tibble(Name = "John", Gender = "Male",
Age = 25, Major = "Statistics"))
## # A tibble: 4 x 4
## Name Gender Age Major
## <chr> <chr> <dbl> <chr>
## 1 Ken Male 24 Finance
## 2 Ashley Female 25 Statistics
## 3 Jennifer Female 23 Computer Science
## 4 John Male 25 Statistics
向persons 数据框中添加两个新列表示每个人是否已注册和其手头的项目数量:
cbind(persons, Registered = c(TRUE, TRUE, FALSE),
Projects = c(3, 2, 3))
## Name Gender Age Major Registered Projects
## 1 Ken Male 24 Finance TRUE 3
## 2 Ashley Female 25 Statistics TRUE 2
## 3 Jennifer Female 23 Computer Science FALSE 3
rbind() 和cbind() 不会修改原始数据,而是生成一个添加了行或列的新数据框。
函数expand.grid() 可生成多个属性水平值所有组合(笛卡儿积) 的数据框:
expand.grid(type = c("A","B"), class = c("M","L","XL"))
## type class
## 1 A M
## 2 B M
## 3 A L
## 4 B L
## 5 A XL
## 6 B XL