#R的学习笔记02(《R数据分析指南与速查手册》)


title: "R的学习笔记03"
author: "ks_c"
date: "2021/1/28"
output: html_document


    昨日在bookdown网站上看到一本书R数据分析指南与速查手册,看起来挺不错,奈何网络奇差,每次打开bookdown网站时都花费不少时间,又无法直接下载,故在阅读过程中做记录于此。后时若用到,则不必费力再登陆彼网站。
郭晓,R 数据分析指南与速查手册,bookdown.org

<font face="宋体">以下为第一章的内容。</font>

1. 快捷键

  1. 脚本编辑窗口:
  • 新建脚本:Ctrl+Shift+N
  • 代码提示与补全:Tab
  • 注释或取消注释:Ctrl+Shift+C
  • 运行所选代码:Ctrl+Enter
  • 运行全部代码:Ctrl+Shift+Enter
  • 全选:Ctrl+A
  • 选择:Shift+箭头
  • 删除行:Ctrl+D
  • 撤销:Ctrl+Z
  • 重做:Ctrl+Shift+Z
  • 赋值符:Alt+-
  • 代码折叠:Alt+L
  • 代码展开:Shift+Alt+L
  • 保存本脚本:Ctrl+S
  • 保存全部脚本:Ctrl+Alt+S
  • 增加缩进:选中代码后,Tab(可包括多行)
  • 减小缩进:选中代码后,Shift+Tab
  • 智能缩进:选中代码后,Ctrl+I
  • 智能缩进加智能空格:Ctrl+Shift+A(更高级的代码格式规范化工具,可参考formatR包)
  • 选择与替换:Ctrl+F
  • 提取函数:Ctrl+Alt+X(RStudio 可以分析某一代码段,并自动将其转换成一个可- 重复使用的函数。任何在选择的代码内的“自由的”变量,即那些被引用但没有被创建的变量,将被转化为函数的参数)
  1. 命令窗口中:
  • 历史中的上一条命令:向上箭头
  • 历史中的下一条命令:向下箭头
  • 中断运行的代码:Esc
  • 清除命令窗口中的内容:Ctrl+L

2.常见运算符

运算符 含义
[ ] [[ ]] 索引(关于两者之间差异请见这篇笔记 )
:: ::: 使用名称访问变量(一般使用::)
$ @ 元素提取、位置提取(更常用$)
^ 乘方
- + 负、正
: 创建数列(x<-c(1:10)#创建1到10的一个数列)
%任意% 特殊运算符
a%in%b#判断a是否在b中,返回T or F
%>%管道符号,见这里
* / 乘、除
+ - 加、减
==、!=、<、>、<=、>= 比较运算符
! 逻辑非
&、&& 逻辑与
I (竖线,enter上遍的键那个) 逻辑或
~ 非,与!=等价
-> 、->> 向右赋值
= 赋值(右边变量的值给左边变量)
<- 、<<- 赋值(同上)
? 帮助

3. 关于换行

分号; 一行执行多条命令(谁会用呢)

 a <- 1;b <- 2
 a
[1] 1
 b
[1] 2

paste0( )函数:来凝结多行字符串

string1 <- "this is a long string 
+ with a ‘\n’  "
[1] "this is a long string \nwith \n"
#如果赋值时直接在字符串中分行,那么最终会出现一个换行符"\n"

 a <- paste0('this is the first line ',
+             'this is the second line')
 a
[1] "this is the first line this is the second line"
#如果用paste0()函数则不会出现

paste()和paste0()之间的区别在于:

paste(..., collapse ="" , recycle0 =F)

paste(..., sep="", collapse ="" , recycle0 =F)函数中多了一个sep参数,用来设置分隔符。

4. ifelse控制语句

类似Excel中的=if()函数。
在Excel中,=if(条件,值为T则,值为F则),在Rstudio中可以用ifelse()函数实现。

 x <- c(6:-4)
 y <- sqrt(ifelse(x >= 0, x, NA))#如果x大于0,那么就取x的值进行计算,否则就是NA。
x
[1]  6  5  4  3  2  1  0 -1 -2 -3 -4
y
 [1] 2.449490 2.236068 2.000000 1.732051 1.414214 1.000000
 [7] 0.000000       NA       NA       NA       NA

多重套娃

a <- ifelse(value1,  value1_if_true,
            ifelse(value2,  value2_if_true,
                   ifelse(value3,  value3_if_true,
                          value_if_false)))

5. switch()函数

switch(EXPR, x1, x2, x3, ...., xn ):数值EXPR为几,就返回x1到xn中的第几个。0<EXPR<=n,否则就会返回NULL[1]

x <- switch(1,'missile', 'cancle', 'dissle')
x
[1] "missile"
x <- switch(4,'missile', 'cancle', 'dissle')
x
NULL

如果后面不是字符串而是变量,那么返回的值为该变量(该变量内所有值),而非返回该向量内的第几个元素(哪怕只有一个向量时)

 y <- c('missile', 'cancle', 'dissle')
 z <- c('pissile','bassle')
 x <- switch(2,y,z)
 x
[1] "pissile" "bassle" 

 y <- c('missile', 'cancle', 'dissle')
 x <- switch(1,y)
 x
[1] "missile" "cancle"  "dissle" 

字符串来说,其用法如下:

switch(condition.string,
case.str1=ret1,
case.str2=ret2,
case.str2=ret2,
...)
而最后返回的值为和condition.string匹配的case.str的ret的值

s <- "color"
switch(s, "color" = "red", "shape" = "square", "length" = 5)
[1] "red"

6. 循环语句:for、while、repeat

6.1 for

for (variable in vector) {
function
}
vector为向量或列表,variable依次变成vector中的值,然后对其进行操作。
function为要进行的操作。

(直接摘抄的)例子:

a <- double(5)  #产生5个0
for (i in 1:length(a)) {
  a[i] <- i^2
}           #length(a)为5,令i依次取1到5,然后a的第i个元素a[i]被赋值为i^2

a
[1]  1  4  9 16 25

b <- list("Appale",1,FALSE)    #b为列表
item <- character()            # item为字符串变量
for (i in b) {                 # i依次取b中元素,
  item <- c(item,mode(i))      #mode()为判断元素类别
}                              #利用mode()判断 i 的类别,新的item变量为旧item变量加上mode(i)
item.mode
[1] "character" "numeric"   "logical"

始终要记住,R是一款newbeer的统计软件而非newbeer的编程软件。
利用向量化的操作比用循环对元素进行操作要更高效,且代码更加简洁。能用向量化的操作时应避免用循环操作。
以上代码用向量化操作可以写为:

b <- list("Appale",1,FALSE)
item.mode <- sapply(b,mode)#

sapply()函数:类似于lapply函数,但输入为列表,返回值为向量

sapply(X, FUN, ..., )
X:列表、矩阵、数据框
FUN:自定义的调用函数
sapply(b, sum)# 求列表中各元素的和
sapply(b,mode)# 判断各元素类型

6.2 while

当条件cond满足时,重复执行表达式expr,直到条件cond不满足为止。

while (cond) {
expr
}

例子:

i <- 1
while (i < 6) {
  print(i)
  i = i + 1
}
 [1] 1
 [1] 2
 [1] 3
 [1] 4
 [1] 5

6.3 repeat

repeat{}和rep()函数不同。
rep(x,times,length.out,each) 函数:将x重复times次,或者重复到length.out的长度

 a <- 2:8
 rep(a,times=2)
 [1] 2 3 4 5 6 7 8 2 3 4 5 6 7 8

 rep(a,length.out=2)#重复结果的长度为2
[1] 2 3

rep(a,each=2)#每个值重复两次
 [1] 2 2 3 3 4 4 5 5 6 6 7 7 8 8

rep(a, each=3,length.out=10)
 [1] 2 2 2 3 3 3 4 4 4 5

而repeat{}则是重复执行花括号内的命令

x <- 1
repeat {
  print(x)
  x <- x + 1
  if (x == 6) {
    break
  }
}
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5

7. 定义函数

形式如下:

FuncName <- function (arglist) {
expr
return(value)
}
argilist:参数列表,用, 隔开。
expr:要执行的命令。
return():给出返回结果,如果不写return语句,则将函数最后一个赋值语句作为返回值。如果不想返回任何对象,则可以将return的参数空缺,即写为return()。
当使用参数时,如果没有指定参数名,则按顺序赋值,如果指定了参数名,可以不按顺序赋值。对于已经指定了默认值的参数,可以在使用时不指定参数值。

类似python,不再介绍。

8. R包

常用的R包:可参考 https://support.rstudio.com/hc/en-us/articles/201057987-Quick-list-of-useful-R-packages

按应用领域分类的R包,可参考 https://cran.r-project.org/web/views/

  • 包的安装:用install.packages("包的名字")
  • 包的加载:用library(包的名字)
  • 从环境中移除包:detach("package:包的名字", unload=TRUE)
  • 卸载包:remove.packages("包的名字")

<center><h1> 9. 常用函数</h1></center>

9.1. 常用数学函数

函数 描述
abs(x) 绝对值
sqrt(x) 开平方
ceiling(x) 向上取整
floor(x) 向下取整
trunc(x) 0-x的整数部分
round(x,digits=n) 舍入至n位小数
signif(x,digits=n) 该数字一共n个数(整数+小数)
cos(x) & sin(x) & tan(x) 三角函数
acos(x) & asin(x) & atan(x) 反三角函数
log(x,base=n) 取以n为底,x的对数
log10(x) 以10为底,x的对数
exp(x) 指数函数:以e为底的指数

9.2. 统计函数

函数 描述
mean(x) 均值
media(x) 中位数
sd(x) / var(x) 标准差/方差
mad(x) 绝对中位差
quantile(x, probs) 分位数
range(x) 全域
sum(x) 求和
diff(x, lag=n) 滞后n位的滞后差分…[1]
min(x)/max(x) 极值
scale(x, center=T, scale=T) 中心化/标准化处理[2]
cov(x) 协方差

[1] : 滞后差分:

x<-c(1,5,23,29)
diff(x)
[ 1 ] 4,8,6

[2] : scale(x):标准化;scale(x,scale=F):中心化。

9.3概率函数

概率函数分为4类:密度函数、分布函数、分位数函数、生成随机数。
根据不同的分布,又分为正态分布、均匀分布等等,二者组合成为具体的函数,在R中,前面4种类型用下面字母打头,之后的函数如下表所示:

d = 密度函数( density,y轴的值)
p = 分布函数( distribution function)
q = 分位数函数( quantile function)
r = 生成随机数(随机偏差Random error)

缩写 分布名称
norm 正态分布
t t分布
chisq 卡方分布
f F分布
unif 均匀分布
logis 逻辑分布
singrank wilcoxon符号秩和分布
wilcox wilcoxon秩和分布
beta Beta分布
binom 二项分布
exp 指数分布
geom 几何分布
pois 泊松分布

对数

其余详见下图


分布名称与缩写

概率为0.95的N~(0,1)的分位数为1.64

qnorm(p=0.95,mean=0,sd=1)
[1] 1.644854

概率为0.99的N~(0,1)的分位数为1.64

qnorm(p=0.99, mean=0, sd=1)
[1] 2.326348

分位数为1.64的N~(0,1)的概率为0.95

pnorm(q = 1.64,0,1)
[1] 0.9494974

pnorm()和qnorm()之间的值可以互相转化

runif(n, min, max)为随机(r)生成符合均匀分布(unif)的n个数据,并不是run if。

9.4. 工作空间函数

在R中,所有反斜杠\代表转义,工作路径用两个反斜杠或者正斜杠。


工作空间管理

ls(all.names=TRUE): 得到包含隐藏变量(以点开头的变量)的列表。

.Last.value:得到上次运行的结果

search(): 查看已经载入的包。

library():查看已经安装的包。

data(dsname,package="pkgname"):不载入某个包的情况下,使用该包的某个数据

9.5. 帮助函数

获取函数的帮助:?后接函数名,函数可不加括号,显示函数的帮助文档。

获取的帮助:用命令help(package="包的名字")。

获取函数源代码:命令窗口中输入函数,不加括号并回车后
  有时候这个函数可能是一个类函数(Generic Function),如plot函数,则先使用methods() 函数来查看这个类函数的列表,找到具体需要的函数如plot.default,使用?plot.default进行查看。

获取特殊符号的帮助,如[[,if,用help("特殊符号")

其他帮助命令见下图:


帮助命令




title: "R的学习笔记04"
author: "ks_c"
date: "2021/1/29"
output: html_document


<font face="宋体">以下为R数据分析指南与速查手册 第二章的内容</font>

2.1 向量

注意事项

  • 向量内部的数据是同一类型

b <- c(1,'a')
b
[1] "1" "a" #这里的1和a都是字符串
typeof(b)
[1] "character"

  • 可以个不存在的元素赋值,如果新赋值的元素与旧元素间有多个不存在的元素,那么这几个元素将变成NA。

x <- 1:5
x[8] <- 6
x
[1] 1 2 3 4 5 NA NA 6
x["a"] <- 8
x
a
1 2 3 4 5 NA NA 6 8

  • 元素名

b <- c(x1=1.2,3.5,x3=pi)
names(b)
[1] "x1" "" "x3"
b
x1 x3
1.200000 3.500000 3.141593

names(b)[2] <- "x2"
names(b)[1] <- "x1_0"
b
x1_0 x2 x3
1.200000 3.500000 3.141593

  • 向量删除

x <- c(0.5,1,100)
删除第1个元素
x <- x[-1]
x
[1] 1 100
x <- x[-length(x)] # 删除结尾元素
x
[1] 100

  • 向量查询

x[x>3.1&x<=8]
[1] 4 5 6 7 8

&、|、!为向量中各元素分别求“与”、“或”、“非”,而&&、| |为向量第一个元素求“与”、“或”。 如果要求向量内部所有元素求“与”,用函数all,如果要求向量内部所有元素求“或”,用函数any

c(T,T,F)&c(T,F,F)
[1] TRUE FALSE FALSE
c(T,T,F)&&c(T,F,F)
[1] TRUE
all(c(T,T,T))&T
[1] TRUE
all(c(T,T,F))&T
[1] FALSE
all(c(T,T,F))
[1] FALSE
all(c(T,T,T))
[1] TRUE
any(c(T,T,T))
[1] TRUE
any(T,T,F)
[1] TRUE

  • %in%:判断运算符前面的对象的各元素是否在后面对象的元素中,返回值的长度总与前面向量的长度相同。如:

c("a","b") %in% c("b","d")
[1] FALSE TRUE

is.element(x, y)类似于x%in%y

x <- 1:4;y <- 3:5
is.element(x,y)
[1] FALSE FALSE TRUE TRUE

which函数:不仅查询满足条件的值是多少,还可以查询他们在原向量中的位置。
其用法为:

which(x, arr.ind = FALSE, useNames = TRUE)

x:逻辑向量,返回元素为TRUE的位置。
如果仅需知道第1个为TRUE的位置,在后面加一个[1]即可,例如:

x <- c(1:6)
x
[1] 1 2 3 4 5 6
which(x>3)
[1] 4 5 6
which(x>3)[1]
[1] 4

-排序

x <- c(5:1,6,pi)
x
[1] 5.000000 4.000000 3.000000 2.000000 1.000000
[6] 6.000000 3.141593
y1 <- x[order(x)]# order()函数从小到大排序
y1
[1] 1.000000 2.000000 3.000000 3.141593 4.000000
[6] 5.000000 6.000000

y2 <- x[order(x,decreasing = TRUE)] # 用order()函数从大到小排
y2
[1] 6.000000 5.000000 4.000000 3.141593 3.000000 2.000000 1.000000

y12 <- sort(x) # 用sort函数
y12
[1] 1.000000 2.000000 3.000000 3.141593 4.000000 5.000000 6.000000
y22 <- sort(x,decreasing = TRUE) #从大到小排
y22
[1] 6.000000 5.000000 4.000000 3.141593 3.000000 2.000000 1.000000

关于向量的其他常见函数,请见troubleisafriend,
R语言常用数学函数

位置最大、最小值所在的位置用函数which.max和which.min

  • 向量的翻转

x <- seq(2,10,by=2)
x <- x[length(x):1]
x
[1] 10 8 6 4 2

x <- rev(x)
x
[1] 2 4 6 8 10

  • 向量的集合运算

交集:intersect(x, y);
并集:union(x, y);
差集:setdiff(x, y)[1]
集合是否相等:setequal(x, y);
确定元素是否是集合的某个元素:is.element(x, y),它等价于x %in% y
以上函数只能对两个变量进行计算。
使用Reduce(function, x, init, right = FALSE, accumulate = FALSE)函数[2]可以批量操作:

Reduce(intersect, list(a,b,d))

[1] : 除去a中b的部分(A-B)
[2] : 将x中第1、2元素进行function操作,然后对操作完的值和第三个元素进行function操作,知道用尽x内的元素详见

  • 向量的算术运算
  • 加:+
  • 减:-
  • 乘:*
  • 除:/
  • 取模(余数):%%
  • 整除:%/%
  • 乘方:^或**

2.2. 简单列表

list可以为任意类型数据,一般函数的输出结果均为list。

任意几个列表可以合成一个新列表。

  • 列表的串联和元素插入

如果我们需要让两个列表的元素组成新的列表,依然用函数c将多个列表连接起来,返回的是列表而不是向量。
也可以用append()函数。

append(x, values, after = length(x))(
append函数也可用于向量,也是取向量values中的元素。
如果原列表的元素有名字,则新列表的元素继承其名字,如果原列表元素没有名字,在append函数中没有添加名字的功能,可以在之后单独用names()函数添加名字。

> x1 <- list(a=1,b="Apple",c=TRUE,d=1:3)
> x2 <- list(e=5+3i,f=c(1.5,2.6))
> # 列表的元素作为新列表的元素
> y1 <- append(x1,x2)
> y1
## $a
## [1] 1
## 
## $b
## [1] "Apple"
## 
## $c
## [1] TRUE
## 
## $d
## [1] 1 2 3
## 
## $e
## [1] 5+3i
## 
## $f
## [1] 1.5 2.6

>length(y1)
[1] 6
y12 <- c(x1,x2)
y12
## $a
## [1] 1
## 
## $b
## [1] "Apple"
## 
## $c
## [1] TRUE
## 
## $d
## [1] 1 2 3
## 
## $e
## [1] 5+3i
## 
## $f
## [1] 1.5 2.6

length(y12)
## [1] 6
# 向量的元素作为新向量的元素
y2 <- append(x1,1:5)
y2
## $a
## [1] 1
## 
## $b
## [1] "Apple"
## 
## $c
## [1] TRUE
## 
## $d
## [1] 1 2 3
## 
## [[5]]
## [1] 1
## 
## [[6]]
## [1] 2
## 
## [[7]]
## [1] 3
## 
## [[8]]
## [1] 4
## 
## [[9]]
## [1] 5

length(y2)
## [1] 9
# 列表本身作为新列表的元素
y3 <- list(x1,x2)
y3
## [[1]]
## [[1]]$a
## [1] 1
## 
## [[1]]$b
## [1] "Apple"
## 
## [[1]]$c
## [1] TRUE
## 
## [[1]]$d
## [1] 1 2 3
## 
## 
## [[2]]
## [[2]]$e
## [1] 5+3i
## 
## [[2]]$f
## [1] 1.5 2.6

length(y3)
## [1] 2

当在append函数中指定after值的时候,可用于元素的插入

2.3 矩阵

矩阵本质上是由维度的向量。向量能够进行的操作矩阵也可以进行。

矩阵创建

matrix(data = , nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL)
byrow=F为按列进行排列,在这里我详细说明。

矩阵的提取

[ ]内只有一个参数时按列提取

x <- matrix(1:8,nrow=2,byrow=T)
x
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8

x[2]
5

length(x)
8

矩阵的拼接

横向拼接:cbind,
纵向拼接:rbind,

被拼接的对象可以是矩阵,也可以是向量。他们在拼接方向需要有相同的维度。

#dim(x)可以查看维度
> dim(x)
[1] 2 4

当横向拼接向量时,向量被视为行向量;当纵向拼接向量时,其被视为列向量。

m1 <- matrix(1:8,nrow = 2)
m2 <- matrix(1:4,nrow = 2)
m3 <- matrix(1:12,nrow = 3)
v1 <- 1:4
v2 <- 1:3
cbind(m1,m2)
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    3    5    7    1    3
## [2,]    2    4    6    8    2    4
rbind(m1,m3)
##      [,1] [,2] [,3] [,4]
## [1,]    1    3    5    7
## [2,]    2    4    6    8
## [3,]    1    4    7   10
## [4,]    2    5    8   11
## [5,]    3    6    9   12
rbind(m1,v1)
##    [,1] [,2] [,3] [,4]
##       1    3    5    7
##       2    4    6    8
## v1    1    2    3    4
cbind(m3,v2)
##               v2
## [1,] 1 4 7 10  1
## [2,] 2 5 8 11  2
## [3,] 3 6 9 12  3

特殊矩阵的创建

  1. 全0矩阵(初始化)

matrix(data = 0, nrow = 2, ncol = 2)即可得到2 x 2的全部为0的矩阵

  1. 对角阵

diag(x = 1, nrow, ncol, names = TRUE)

  • x可以是数字或矩阵或一维数组
  • names=T:如果矩阵x 有名称则继承其名称。

当仅包含两个参数,第1个参数为单元素,第2个参数为整数n时,表示创建n维对角矩阵,每个对角元素都为第1个参数。
第1个元素的类型可以是整数型、实数型、复数型或逻辑型,不能是字符串型。对逻辑型来说,非对角的地方为FALSE。

也可以创建对角线上元素不同的矩阵,此时将对角线上的元素以向量的方式作为diag的第一个参数,矩阵的维度与该向量的长度相同。如果指定维度,若对角线上元素长度小于行数与列数中的最小值,指定对角线向量会复制多份首尾相连。

当x为矩阵时,则不可以指定nrow和ncol,直接输出x对角线上的值。

> diag(x,length(x))
     [,1] [,2] [,3] [,4]
[1,]    1    0    0    0
[2,]    0    2    0    0
[3,]    0    0    3    0
[4,]    0    0    0    4

x<- matrix(1:20)
> dim(x) <- c(4,5)
> x
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20
> diag(x)
[1]  1  6 11 16

行列名称

m1 <- matrix(1:8,nrow = 2, dimnames = list(c("r1","r2"),c("c1","c2","c3","c4")))
m1
##    c1 c2 c3 c4
## r1  1  3  5  7
## r2  2  4  6  8

rownames(m1) <- c("p1","p2")
m1
##    c1 c2 c3 c4
## p1  1  3  5  7
## p2  2  4  6  8

row.names(m1) <- c("R1","R2")
m1
##    c1 c2 c3 c4
## R1  1  3  5  7
## R2  2  4  6  8

dimnames(m1) <- list(c("rr1","rr2"),c("cc1","cc2","cc3","cc4"))
m1
##    cc1 cc2 cc3 cc4
## rr1  1  3  5  7
## rr2  2  4  6  8

矩阵的提取

m2 <- m[1 , , drop = FALSE]
单行矩阵

矩阵转置、翻转、旋转

转置:
t(m1)

上下翻转:
m1[nrow(m1):1, ]

左右翻转:
m1[ ,ncol(m1):1]

顺时针90度旋转:
t(apply(m1, 2, rev))

逆时针90度旋转:
t(apply(t(m1), 2, rev))

运算

矩阵级运算1
矩阵级运算2

2.4 高维数组

数组是具有维度(dim)属性的向量。矩阵是一种特殊的数组(一维)。
array(x, c(3, 4, 2))二维的两个3 x 4的矩阵组成的数组

>x <- array(1:3, c(2,4,2))
## , , 1
## 
##      [,1] [,2] [,3] [,4]
## [1,]    1    3    2    1
## [2,]    2    1    3    2
## 
## , , 2
## 
##      [,1] [,2] [,3] [,4]
## [1,]    3    2    1    3
## [2,]    1    3    2    1

数组拼接

abind包中的abind()函数:abind(..., along=N)。

x
y<- x+100
#按行拼接
abind(x,y, along=1)

# 列方向拼接
abind(x,y, along=2)

# 页方向拼接
abind(x,y, along=3)

# 新的维度上拼接,新维度作为第1维,之前的维度顺次后移
abind(x,y, along=0)

2.5 数据框

数据框是一种特殊的列表,列表中每个元素都是一个有名字的向量,且这些向量的长度相同。不同的向量可以是不同类型的。数据框是统计分析中最常用的数据结构。

创建

name <- c("Alice","Bob","Christien")
age <- c(10,20,14)
gender <- c("F","M","F")
weight <- c(25,50,30)
df <- data.frame(name,age,gender,weight)
df
##        name age gender weight
## 1     Alice  10      F     25
## 2       Bob  20      M     50
## 3 Christien  14      F     30

如果有字符串,dataframe中的字符串会被认为是因子类型。用stringsAsFactor=F可以阻止变为字符串。

所谓因子型,简单来说是包含顺序的字符串,顺序可由用户指定。在建模时,会被作为整数处理。

# 抑制字符串向因子型的转换
df2 <- data.frame(name,age,gender,weight,stringsAsFactors=FALSE)
df2

行名,列明的创建、提取和修改。

向量名被默认作为数据框的列名。
矩阵列名也会默认作为数据框列名。
如果数据框没有指定列名,则列名默认为“V1”、“V2”…,如果数据框没有指定行名,则行名默认为“1”、“2”、“3”…。
获取数据框列名,可用names函数或colnames函数。
获取数据框行名,可用row.names函数或rownames函数。
对数据框来说,row.names函数效率更高,因而推荐使用row.names函数。

在实际数据分析中,修改行名的做法很少见,更多的是增加一个ID列,然后做相应的修改。

提取数据时如果需要保持为单列数据框,可以添加drop = FALSE参数

# 给一个尚不存在的列赋值,即增加该列
df$new <- 1:4

df[5] <- NULL # 删除该列
# 可以通过序号的方式增加1列
df[5] <- c(T,F,F,T)
df

df <- data.frame(name,age,gender,weight) # 注意此处字符串会转化为因子型

df5 <- rbind(df3,df4)

df7 <- cbind(df1,df6)

#将相同的列合并,可以用merge函数
#merge函数会删除重复的相同列,而且可以根据相同列的顺序合并(相当于Excel中的=vlookup)

条件查询

subset(x, subset, select, drop=F)
subset参数可以提取行方面满足条件
select参数可以为列方面选取的范围

df2 <- subset(df,subset = name!="Einstein"&age>10,select = c(age:weight,height))
# !=为不等于
df2

排序

如果需要根据一列或多列的顺序,对其他列做相应的调整,可以使用order函数。如果需要将所有列都按降序排序,则增加decreasing = TRUE参数。如果大多数升序,某些降序,在降序的列前加-rank函数(如果是数值型,仅加负号就可以)。如果大多数降序,某些升序,在升序前加-rank函数函数,且添加decreasing = TRUE参数。下面是一些列子:

name <- c("Alice","Bob","Christien","Einstein")
age <- c(10,20,14,25)
gender <- c("F","M","F","M")
weight <- c(25,50,30,54)
nationality <- c("USA","UK","China","German")
height <- c(1.2,1.65,1.43,1.75)
df <- data.frame(name,age,gender,weight,nationality,height)
#gender、weight两列将序排列
df2 <- df[order(df$gender,df$weight,decreasing = TRUE),]
# gender降序,其余升序排列
# gender列前加一个-rank()就表示与默认排序方式不同。
df3 <- df[order(-rank(df$gender),df$weight),]
#gender升序,weight降序(数值变量直接加-即可)
df4 <- df[order(df$gender,-df$weight),]


title: "R的学习笔记04"
author: "ks_c"
date: "2021/2/2"
output: html_document


<font face="宋体">以下为R数据分析指南与速查手册 第三章的内容</font>

导出

导出变量

使用save(..., list = character(),file = stop("'file' must be specified"))可以保存单个变量或一些变量。文件名为.rda或.Rdata。

  • ...:要存储的变量
  • list:变量标签/名称
  • file:文件名及路径

如果想保存整个环境,用save.image函数。常用用法为save.image(file = ".RData"),用file指定文件名即可。

导出txt或csv

导出为txt格式:

write.table(x, file = "",
append = FALSE,
quote = TRUE,
sep = " ",
eol = "\n",
na = "NA",
dec = ".",
row.names = TRUE,
col.names = TRUE,
qmethod = c("escape", "double"),
fileEncoding = "")

导出文件中:

  • 字符串型数据将用引号括起来,如果不想有引号,可设置quote = FALSE。
    (注意导出的csv文件中也是如此,只是如果用Excel打开的话,其中的引号不显示出来,如果用文本查看器如Notepad++打开,就可以看到引号。)
  • 如果要保存的数据不是数据框格式,会被转化为数据框格式,然后再保存为csv或txt文件。
  • 导出文件中默认包含行名(行序号)和列名,如果不需要,在write.table中可以设定row.names = FALSE及col.names = FALSE,在write.csv中设定row.names=FALSE(在write.csv中,可以通过col.names给csv文件修改列名,但是不能取消其列名)。
  • 更多参数设置,可查看write.table的帮助文档。在write.csv中,会将行名与列名交叉格以空字符串输出,但write.table会将其空缺。这会导致他们重新导入时,对行名的处理不同。
# 数据生成
name <- c("Alice","Bob","Christien","Einstein")
age <- c(10,20,14,25)
gender <- c("F","M","F","M")
weight <- c(25,50,30,54)
nationality <- c("USA","UK","China","German")
height <- c(1.2,1.65,1.43,1.75)
example_df <- data.frame(name,age,gender,weight,nationality,height)

# 保存
write.csv(example_df, file = "example_df.csv")
write.table(example_df, file = "example_df.txt")
write.table(example_df, file = "example_df2.txt",quote = FALSE)#字符串没有引号

导出图片

直接保存而不展示图片:

  • 新建保存格式(称之为一个图形设备),如png、jpg、pdf(pdf是矢量图),
  • 运行绘图相关的代码,
  • 关闭图形设备。
png("example_plot.png") # 新建一个图片保存格式,png可以是jpg、pdf等
plot(1:10) # 绘图
dev.off() # 关闭图形设备

图片的长、宽、分辨率等参数可参考png等的帮助文档。

如果已经画好了图,可以使用如下代码输出到文件中。

dev.copy(png, 'example_plot2.png')
dev.off()

如果最开始打开的是Windows窗口,则可用savePlot()函数,其用法为:

savePlot(filename="Rplot",
type=c("wmf", "png", "jpeg", "jpg", "bmp", "ps"),
device=dev.cur())

#例子:
windows(width = 9, height = 9, rescale = "fit")  # 打开一个Windows窗口
plot(1:10,type = "l")
savePlot(filename="Myplot",type="pdf")
# savePlot(filename="Myplot",type="png")
## 支持下列格式:"wmf", "emf", "png", "jpg", "jpeg", "bmp", "tif", "tiff", "ps", "eps", "pdf"
dev.off()

导出文本

readr::write_file(txt, file_name.txt", append = FALSE)

writeLines(txt, con = fileConn,sep = "")
close(fileConn)

sink("cat.txt")
操作
sink()

cat(... = ,file = ,sep = ,fill = ,labels = ,append = )

fileConn<-file("writeChar.txt")
writeChar(txt, con = fileConn, eos = NULL, useBytes = FALSE)
close(fileConn)

writeChar

R与python通用的数据

feather

#R中
library(feather)
path <- "my_data.feather"
write_feather(df, path)
df <- read_feather(path)

#py中
import feather
path = 'my_data.feather'
feather.write_dataframe(df, path)
df = feather.read_dataframe(path)

数据载入

数据

read.table默认的分隔符为空格,read.csv2默认的分隔符为分号;
可以改变默认的分隔符。

read.csv(file,
header = TRUE,
sep = ",",
quote = """,
dec = ".",
fill = TRUE,
comment.char = "", ...)

按行或单元导入(表格数据)
按行导入用readLines,按单元导入用scan

文本

整体读取可用readr::read_file,
按行读取可用readLines,如

txt<- read_file("write_file.txt")

title: "R的学习笔记04"
author: "ks_c"
date: "2021/2/2"
output: html_document


<font face="宋体">以下为R数据分析指南与速查手册 第四章的内容</font>


tidyverse包做探索性数据分析

  • 数据变化
    1 filter
    2 select
    3 arrange
  • 多表融合
  • 增加新列
    1 mutate
    2 mutate与group_by
    3 mutate_all
    4 mutate_at
    5 mutate_if
  • 数据汇总
    1 summarise与group_by
    2 summarise_all
    3 summarise_at
    4 summarise_if
  • 函数复用
  • 可视化

1. 数据变换总结

  • 行去重:distinct(.data, …, .keep_all = FALSE)
  • 行筛选:filter()
  • 列筛选:select()
  • 行排序:arrange()
  • 长转宽:spread(data, key=键所在列, value=键值所在列)
  • 宽转长:gather(data, 需要转换的各列, key = “新建的键名”, value = “新建的键值名”)
  • 列合并:unite(data, col=新列, 需要合并的各列, sep = "_", remove = TRUE)
  • 列分裂:separate(data, col, into=c(“列1”,“列2”,…), sep = “[^[:alnum:]]+”)
  • 嵌套与取消嵌套:nest()、unnest()

1.1 filter

filter进行行筛选,各逗号分隔的条件需同时满足,常用筛选条件有:

>, >=, <, <=, !=(不等于) , == ,near() , is.na(), %in%(前者是否在后者里面,返回值为T/F), between(x, left, right)

由于可能存在舍入误差,浮点数最好不用 == 而用near。

&, |, !, xor()(异或)

1.2 select

进行列筛选,各逗号分隔的条件任满足其一即可,常用辅助筛选函数有:

:(从a列到b列), - (除了这些列)
starts_with()、ends_with()、contains()、matches()、num_range()、one_of()、everything()、last_col()

1.3 arrange

对行进行排序,可以有多个排序条件,
降序:desc()

2. 多表融合总结

将两个或多个表,通过共同的列联结起来,常见的操作包括:

  • 左联结:left_join(x, y, by = NULL)
  • 右联结:right_join(x, y, by = NULL)
  • 内联结:inner_join(x, y, by = NULL)
  • 全联结:full_join(x, y, by = NULL)
  • 半联结:semi_join(x, y, by = NULL)
  • 反联结:anti_join(x, y, by = NULL)
  • 多个表的联结:list(x1, x2, x3,…) %>% reduce(····_join, by = NULL)

将具有相同列的两个表或多个表,对行进行集合操作

  • intersect(x, y, …)
  • union(x, y, …)
  • union_all(x, y, …)
  • setdiff(x, y, …)
  • setequal(x, y, …)
  • list(x1, x2, x3,…) %>% reduce(*_join, by = NULL)

3. 增加新列总结

对原有的列进行运算,得到长度与数据行数相同的新列。

分组与取消分组:group_by()、ungroup()

  • 增加新列:

    • mutate()
    • mutate_all(.tbl, .funs, …)
    • mutate_at(.tbl, .vars, .funs, …)
    • mutate_if(.tbl, .predicate, .funs, …)
  • 仅保留新列:

    • transmute()
    • transmute_all()
    • transmute_at()
    • transmute_if()

4. 数据汇总总结

分组对列进行统计汇总,统计汇总函数一般含一个数据参数,这个参数为代表多个观测的向量,返回单个数值。当返回多个值时,可以将其转换为list.

数据汇总(一般会与分组结合):
summarise()
summarise_all(.tbl, .funs, …)
summarise_if(.tbl, .predicate, .funs, …)
summarise_at(.tbl, .vars, .funs, …, .cols = NULL)
所有列采用相同汇总函数时也可用map()、map_*(),但其无法和group_by结合
对summarise系列函数,若返回长度大于1的向量,可用list将结果包围。

5. 函数复用总结

单变量
返回列表:map(.x, .f, …)
返回 * 类型的向量:map_(.x, .f, …)( 可以是lgl、chr、int、dbl、raw)
得到输出、打印、保存等其他动作:walk()
返回数据框:map_dfc(.x, .f, …), map_dfr(.x, .f, …, .id = NULL)
条件筛选,返回列表:map_if(.x, .p, .f, …, .else = NULL)、map_at(.x, .at, .f, …)
2维变量:map2(.x, .y, .f, …)、map2_(.x, .y, .f, …)等(没有if和at)
p维变量:pmap(.l, .f, …)、pmap_
(.x, .y, .f, …)等(没有if和at)
递归复用:map_depth(.x, .depth, .f, …, .ragged = FALSE)

6. 可视化总结

ggplot图层:

ggplot(data = <DATA>) +
  <GEOM_FUNCTION>(
    mapping = aes(<MAPPINGS>),
    stat = <STAT>,
    position = <POSITION>
  ) +
  <COORDINATE_FUNCTION> +
  <FACET_FUNCTION> +
  <SCALE_FUNCTION> +
  <THEME_FUNCTION>

GEOM_FUNCTION
离散变量频次:geom_bar
连续变量频次:geom_histogram、geom_freqpoly、 geom_density
离散vs连续:geom_boxplot、geom_violin、并排geom_histogram
离散vs离散:geom_tile(热力图,颜色深浅表示频次),geom_count(点的大小表示频次)、并排geom_bar
连续vs连续:geom_point、geom_bin2d(方形封箱)、geom_hex(6边形封箱)、geom_smooth、geom_line、geom_density2d
3变量: geom_contour(aes(z = z))、geom_tile(aes(fill = z))、geom_raster(aes(fill = z))

MAPPINGS
x、y轴:x、y
点或边框的颜色:color (颜色字符串)
填充颜色:fill (颜色字符串)
形状:shape(最多6种,代表形状的数字)
点的大小、线的粗细:size (毫米为单位的数字)
透明度:alpha
线型:linetype(整数或字符串: 0 = blank, 1 = solid, 2 = dashed, 3 = dotted, 4 = dotdash, 5 = longdash, 6 = twodash)
边框粗细:stoke
group
STAT
“count”
“bin”
“identity”
“boxplot”

POSITION
“stack”:堆积
“identity”:独立重叠
“dodge”:侧面并列
“fill”:堆积归一
“jitter”:扰动
“dodge2”

COORDINATE_FUNCTION
coord_flip:坐标翻转
coord_fixed(ratio = 1/2):固定坐标比例
coord_polar:极坐标
coord_cartesian:笛卡尔坐标(默认,可修改坐标范围)coord_cartesian(xlim = c(0, 5))
FACET_FUNCTION
单变量分面:facet_wrap
双变量分面:facet_grid

点的形状代码

第五章为R markdown的介绍,在

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,757评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,478评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,540评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,593评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,903评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,329评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,659评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,383评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,055评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,337评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,864评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,227评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,820评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,999评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,750评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,365评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,260评论 2 258

推荐阅读更多精彩内容