R语言学习笔记
R语言认识
R语言特点
- 有效的数据处理和保存机制。
- 拥有一整套数组和矩阵的操作运算符。
- 一系列连贯而又完整的数据分析中间工具。
- 图形统计可以对数据直接进行分析和显示,可用于多种图形设备。
- 一种相当完善、简洁和高效的程序设计语言。
- R语言是彻底面向对象的统计编程语言。
- R语言和其它编程语言、数据库之间有很好的接口。
- R语言是自由软件,可以放心大胆地使用,但其功能却不比任何其它同类软件差。
- R语言具有丰富的网上资源。
R语言学习网站
在R官网下载一个R的exe
程序,RStudio
是一个R专用的IDE。
基本操作
R version 4.1.3 (2022-03-10) -- "One Push-Up"
Copyright (C) 2022 The R Foundation for Statistical Computing
Platform: x86_64-w64-mingw32/x64 (64-bit)
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.
R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.
Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.
> getwd() ## 获取当前R工作目录
[1] "C:/Users/myxc/Documents"
> setwd(dir = "D:/R") ## 自定义R工作目录
> getwd() ## 重新查看R工作目录,会发现已经更改为上一步所设置的。
[1] "D:/R"
> list.files() ## 查看R工作目录下的所有文件和文件夹(不能查看嵌套文件夹里的文件)。
[1] "RData" "Study"
> dir() ## 这个命令与上一步相同
[1] "RData" "Study"
> 1 + 2 ## 在R中直接进行计算
[1] 3
> x <- 1 ## 在R中进行赋值
> y = 1 ## 这种赋值操作可以,但是不推荐在R中使用
> z <<- 1 ## 将全局变量“x”赋值为“1”(“<-”此种赋值方式操作得到的是局部变量)
> m <- max(5, 6, 7) # 将“5,6,7”中最大的值赋给m
> n = mean(8, 9, 10) # 将“8,9,10”的平均值赋给局部变量n
> v = sum(3, 4, 5) # 将“3,4,5”的和赋给局部变量v
> ls() # 查看所有变量
[1] "m" "n" "v" "x" "y" "z"
> ls.str() # 查看所有变量及其类型
m : num 7
n : num 8
v : num 12
x : num 1
y : num 1
z : num 1
> str(m) # 查看单个变量及其类型
num 7
> rm(x) # 删除变量x
> x # 局部变量x已经被删除
Error: object 'x' not found
> ls.str()
m : num 7
n : num 8
v : num 12
y : num 1
z : num 1
> rm(m, n) # 同时删除多个变量
> ls.str()
v : num 12
y : num 1
z : num 1
> rm(list = ls()) # 删除所有变量
> ls.str()
> history() # 显示所有历史命令
> history(10) # 显示最后10条历史命令
> save.image() # 保存当前工作空间(会在之前设置的R工作目录中生成一个“.RData”文件)
> q() # 保存当前工作空间
Save workspace image to D:/R/.RData? [y/n]:
R包操作
安装
中科大R镜像:https://mirrors.ustc.edu.cn/CRAN/index.html
官方:https://cloud.r-project.org/
[photos]
[/photos]
R version 4.1.3 (2022-03-10) -- "One Push-Up"
Copyright (C) 2022 The R Foundation for Statistical Computing
Platform: x86_64-w64-mingw32/x64 (64-bit)
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.
R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.
Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.
[Workspace loaded from D:/R/.RData]
> install.packages("vcd") # 安装R包
WARNING: Rtools is required to build R packages but is not currently installed. Please download and install the appropriate version of Rtools before proceeding:
https://cran.rstudio.com/bin/windows/Rtools/
将程序包安装入‘C:/Users/myxc/Documents/R/win-library/4.1’
(因为‘lib’没有被指定)
trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.1/vcd_1.4-9.zip'
Content type 'application/zip' length 1293641 bytes (1.2 MB)
downloaded 1.2 MB
package ‘vcd’ successfully unpacked and MD5 sums checked
The downloaded binary packages are in
C:\Users\myxc\AppData\Local\Temp\RtmpSWB6cz\downloaded_packages
> .libPaths() # 显示R默认安装的包的位置
[1] "C:/Users/myxc/Documents/R/win-library/4.1" "C:/Program Files/R/R-4.1.3/library"
> library() # 显示当前R环境中所有包
> install.packages(c("AER", "ca")) # 同时安装多个包
WARNING: Rtools is required to build R packages but is not currently installed. Please download and install the appropriate version of Rtools before proceeding:
https://cran.rstudio.com/bin/windows/Rtools/
将程序包安装入‘C:/Users/myxc/Documents/R/win-library/4.1’
(因为‘lib’没有被指定)
trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.1/AER_1.2-9.zip'
Content type 'application/zip' length 2498423 bytes (2.4 MB)
downloaded 2.4 MB
trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.1/ca_0.71.1.zip'
Content type 'application/zip' length 243631 bytes (237 KB)
downloaded 237 KB
package ‘AER’ successfully unpacked and MD5 sums checked
package ‘ca’ successfully unpacked and MD5 sums checked
The downloaded binary packages are in
C:\Users\myxc\AppData\Local\Temp\RtmpSWB6cz\downloaded_packages
> update.packages() # 更新R包
Warning: package 'cluster' in library 'C:/Program Files/R/R-4.1.3/library' will not be updated
Warning: package 'MASS' in library 'C:/Program Files/R/R-4.1.3/library' will not be updated
Warning: package 'Matrix' in library 'C:/Program Files/R/R-4.1.3/library' will not be updated
Warning: package 'mgcv' in library 'C:/Program Files/R/R-4.1.3/library' will not be updated
Warning: package 'nlme' in library 'C:/Program Files/R/R-4.1.3/library' will not be updated
Warning: package 'survival' in library 'C:/Program Files/R/R-4.1.3/library' will not be updated
lme4 :
Version 1.1-28 installed in C:/Users/myxc/Documents/R/win-library/4.1
Version 1.1-29 available at https://cran.rstudio.com
有二进制版本的,但源代码版本是后来的:
binary source needs_compilation
lme4 1.1-28 1.1-29 TRUE
Binaries will be installed
trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.1/lme4_1.1-28.zip'
Content type 'application/zip' length 5349899 bytes (5.1 MB)
downloaded 5.1 MB
package ‘lme4’ successfully unpacked and MD5 sums checked
The downloaded binary packages are in
C:\Users\myxc\AppData\Local\Temp\RtmpSWB6cz\downloaded_packages
>
使用
R自带基础包:
- base
- datasets
- utils
- grDevices
- graphics
- stats
- methods
- splines
- stats4
- tcltk
> .libPaths() # 查看R包默认安装位置
[1] "C:/Users/myxc/Documents/R/win-library/4.1" "C:/Program Files/R/R-4.1.3/library"
> library() # 查看本机环境中的所有R包
> library(vcd) # 环境中还未安装“vcd”包
Error in library(vcd) : 不存在叫‘vcd’这个名字的程辑包
> install.packages("vcd") # 安装“vcd”包
> install.packages("AER") # 安装“vcd”包
WARNING: Rtools is required to build R packages but is not currently installed. Please download and install the appropriate version of Rtools before proceeding:
https://cran.rstudio.com/bin/windows/Rtools/
将程序包安装入‘C:/Users/myxc/Documents/R/win-library/4.1’
(因为‘lib’没有被指定)
trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.1/AER_1.2-9.zip'
Content type 'application/zip' length 2498423 bytes (2.4 MB)
downloaded 2.4 MB
package ‘AER’ successfully unpacked and MD5 sums checked
Error in install.packages : ERROR: failed to lock directory ‘C:\Users\myxc\Documents\R\win-library\4.1’ for modifying
Try removing ‘C:\Users\myxc\Documents\R\win-library\4.1/00LOCK’
> library(AER)
载入需要的程辑包:car
载入需要的程辑包:carData
载入需要的程辑包:lmtest
载入需要的程辑包:zoo
载入程辑包:‘zoo’
The following objects are masked from ‘package:base’:
as.Date, as.Date.numeric
载入需要的程辑包:sandwich
载入需要的程辑包:survival
> require(AER)
> help("package:AER") # 显示”AER“包的帮助文档
No documentation for ‘package:AER’ in specified packages and libraries:
you could try ‘??package:AER’
> help(package="AER") # 显示”AER“包的帮助文档
> library(help="AER") # 显示“AER”包的数据集
> NMES1988
Error: object 'NMES1988' not found
> Affairs
Error: object 'Affairs' not found
> ls("package:AER") # 显示包中所有的函数
[1] "dispersiontest" "ivreg" "ivreg.fit" "tobit"
> data(package="AER") # 显示包中所有数据集
> detach("package:AER") # 从内存中移除“AER”包(注意,并不是删除环境中的“AER”包)
> require(AER)
载入需要的程辑包:AER
> remove.packages("AER") # 删除环境中的“AER”包
从‘C:/Users/myxc/Documents/R/win-library/4.1’中删除程序包
(因为没有指定‘lib’)
> # 如何将本计算机环境中的所有R包移植到另一台计算机?(R无备份功能)
Tip: 如何将本计算机环境中的所有R包移植到另一台计算机?(R无备份功能)
# 导出原计算机环境中的所有R包,将所有R包的名字导出为一个文件
> backup_R_package = installed.packages()[,1]
> save(backup_R_package, file = "backup_R_package.Rdata")
# 在新的计算机里遍历循环安装R包
> for (i in backup_R_package) install.packages(i) # 批量安装
获取帮助
> help.start() # 显示帮助文档
If nothing happens, you should open
‘http://127.0.0.1:31250/doc/html/index.html’ yourself
> help(sum) # 打开sum函数的帮助文档
Warning messages:
1: In read.dcf(file.path(p, "DESCRIPTION"), c("Package", "Version")) :
cannot open compressed file 'C:/Users/myxc/Documents/R/win-library/4.1/AER/DESCRIPTION', probable reason 'No such file or directory'
2: In find.package(if (is.null(package)) loadedNamespaces() else package, :
不存在叫‘AER’这个名字的程辑包
> ?sum # 与上一步操作一个意思
Warning messages:
1: In read.dcf(file.path(p, "DESCRIPTION"), c("Package", "Version")) :
cannot open compressed file 'C:/Users/myxc/Documents/R/win-library/4.1/AER/DESCRIPTION', probable reason 'No such file or directory'
2: In find.package(if (is.null(package)) loadedNamespaces() else package, :
不存在叫‘AER’这个名字的程辑包
> args(sum) # 显示sum函数需要哪些参数
function (..., na.rm = FALSE)
NULL
一个R搜索帮助的网站:https://rseek.org
> example("mean") # 获取mean函数的举例
mean> x <- c(0:10, 50)
mean> xm <- mean(x)
mean> c(xm, mean(x, trim = 0.10))
[1] 8.75 5.50
> demo(graphics)
demo(graphics)
---- ~~~~~~~~
Type <Return> to start :
...
> help(package="ggplot2") # 获取ggplot2包的帮助文档
> vignette() # 获取更加规划的官方文档
> help.search("heatmap") # 在本地搜索heatmap相关的内容
> ??heatmap # 与上一步相同
> apropos("sum") # 列出所有包含“sum”关键字的内容
[1] ".colSums" ".rowSums" ".rs.callSummary" ".rs.summarizeDir"
> apropos("sum", mode = "function") # 列出所有包含“sum”关键字的内容,只搜索函数相关
[1] ".colSums" ".rowSums" ".rs.callSummary" ".rs.summarizeDir"
> RSiteSearch("sum") # 联网搜索
A search query has been submitted to http://search.r-project.org
计算结果应很快就在瀏覽器里打开
>
内置数据集
> help(package="datesets") # 打开R中数据集的帮助文档
> help(package="datasets") # 打开R中数据集的帮助文档
> data()
> data() # 显示所有数据集
> rivers # 数据集中的一个河流数据
[1] 735 320 325 392 524 450 1459 135 465 600 330 336 280 315 870 906 202 329 290 1000 600 505 1450
[24] 840 1243 890 350 407 286 280 525 720 390 250 327 230 265 850 210 630 260 230 360 730 600 306
[47] 390 420 291 710 340 217 281 352 259 250 470 680 570 350 300 560 900 625 332 2348 1171 3710 2315
[70] 2533 780 280 410 460 260 255 431 350 760 618 338 981 1306 500 696 605 250 411 1054 735 233 435
[93] 490 310 460 383 375 1270 545 445 1885 380 300 380 377 425 276 210 800 420 350 360 538 1100 1205
[116] 314 237 610 360 540 1038 424 310 300 444 301 268 620 215 652 900 525 246 360 529 500 720 270
[139] 430 671 1770
> rivers <- 1 # 在定义变量的时候,尽量要避开这些变量名
> rivers
[1] 1
> data("rivers") # 如果变量名被覆盖,需要重新加载
> rivers
[1] 735 320 325 392 524 450 1459 135 465 600 330 336 280 315 870 906 202 329 290 1000 600 505 1450
[24] 840 1243 890 350 407 286 280 525 720 390 250 327 230 265 850 210 630 260 230 360 730 600 306
[47] 390 420 291 710 340 217 281 352 259 250 470 680 570 350 300 560 900 625 332 2348 1171 3710 2315
[70] 2533 780 280 410 460 260 255 431 350 760 618 338 981 1306 500 696 605 250 411 1054 735 233 435
[93] 490 310 460 383 375 1270 545 445 1885 380 300 380 377 425 276 210 800 420 350 360 538 1100 1205
[116] 314 237 610 360 540 1038 424 310 300 444 301 268 620 215 652 900 525 246 360 529 500 720 270
[139] 430 671 1770
数据结构
数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。
数据类型
- 数值型,数值可以用于直接结算,加减乘除;
- 字符串型,可以进行连接,转换,提取等;
- 逻辑型, 真或者假;
- 日期型等。
普通数据结构:向量、标量、列表、数组、多维数组。
特殊数据结构:
- perl中的哈希
- python中的字典
- C语言中的指针等
对象:object,它是指可以赋值给变量的任何事物,包括常量、数据结构、函数,甚至图形。对象都拥有某种模式,描述了此对象是如何存储的,以及某个类。
向量
向量:vector,是R中最重要的一个概念,它是构成其他数据结构的基础。R中的向量概念与数学中向量是不同的,类似于数学上的集合的概念,由一个或多个元素所构成。
向量其实是用于存储数值型、字符型或逻辑型数据的一维数组。
用函数c来创建向量。c代表concatenate连接 ,也可以理解为收集collect,或者合并combine。
> x = c(1, 2, 3) # 在R中创建一个数值向量
> x
[1] 1 2 3
> x[1] # R中向量尽然是从1开始计数的?就离谱。
[1] 1
> y = c("one", "two", "three") # 创建一个字符串向量
> y[1]
[1] "one"
> z <- c(TRUE, T, F) # 创建一个布尔值向量
> z
[1] TRUE TRUE FALSE
> v <- True # 布尔值的这种写法在R中是不认可的
Error: object 'True' not found
> c(1:100) # 创建一个从1到100的数值向量
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
[29] 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
[57] 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
[85] 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
> seq(from=1, to=100) # 与上一步作用相同
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
[29] 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
[57] 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
[85] 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
> seq(from=1, to=100, by=2) # 创建一个从1到100,且间隔为2的数值向量
[1] 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75
[39] 77 79 81 83 85 87 89 91 93 95 97 99
> seq(from=1, to=100, length.out=10) # 创建一个从1到100,且长度为10的数值向量
[1] 1 12 23 34 45 56 67 78 89 100
> rep(1, 5) # 创建一个将1重复5次的数值向量
[1] 1 1 1 1 1
> rep(x, 5) # 创建一个将向量x重复5次的数值向量
[1] 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
> x
[1] 1 2 3
> rep(x, each=2, times=3) # 创建一个将向量x中的每个数值重复2次,且数值向量x整体重复3次的数值向量
[1] 1 1 2 2 3 3 1 1 2 2 3 3 1 1 2 2 3 3
> a <- c(1, 2, "three") # 向量中的元素值类型必须为一致,否则会强制转化
> a
[1] "1" "2" "three"
> mode(a) # 向量a中的元素已经被强制转化为字符串类型
[1] "character"
> mode(a[1])
[1] "character"
> x <- c(1, 2, 3, 4, 5)
> y <- c(2, 4, 6, 8, 10)
> z <- x*2+y # R中向量类型的优点:更加方便做统计运算
> z
[1] 4 8 12 16 20
> rep(x, y) # 将数值向量x中的每个元素对应数值向量y中的数值进行重复
[1] 1 1 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5
向量的索引
- 正(负)整数索引;
- 逻辑向量索引;
- 名称索引。
> x <- c(1:100) # 创建一个数值型向量,里面元素从1到100
> x
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
[29] 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
[57] 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
[85] 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
> length(x) # 获取向量x的长度,即其内部有多少元素
[1] 100
> x[1] # x向量中第1个元素
[1] 1
> x[-1] # 显示x向量中除了第一个元素的所有元素
[1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
[30] 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
[59] 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
[88] 89 90 91 92 93 94 95 96 97 98 99 100
> x[c(2:10)] # 访问x向量中第2到第10个元素
[1] 2 3 4 5 6 7 8 9 10
> x[c(2, 6, 78, 99)] # 访问x向量中第2、6、78、99个元素
[1] 2 6 78 99
> x[c(-1, -10:-99)] # 访问x向量中除了第1、第10~第99个元素以外的所有元素
[1] 2 3 4 5 6 7 8 9 100
> x[c(1, -10:-99)] # 访问x向量中除了第1、第10~第99个元素以外的所有元素
Error in x[c(1, -10:-99)] :
only 0's may be mixed with negative subscripts
> x[c(1, -10:-99)] # 但是两种访问方式不能同时出现
Error in x[c(1, -10:-99)] :
only 0's may be mixed with negative subscripts
> y <- c(1:10) # 创建一个数值型向量,里面元素从1到10
> y
[1] 1 2 3 4 5 6 7 8 9 10
> y[c(T, F, T, F, T, F, T, F, T, F)] # 输出y向量中的奇数值(因为序号为奇数对应的值都为TRUE)
[1] 1 3 5 7 9
>
> y[c(F, T)] # 输出y向量中的偶数值
[1] 2 4 6 8 10
> y[c(F, F, T)] # 输出y向量中3的倍数
[1] 3 6 9
> y[c(F, F, T, F, F, T, F, F, T, F, F)] # 输出y向量中3的倍数(注意:此处y向量的长度为10,但是此处对应的布尔值有11个)
[1] 3 6 9
> y[c(F, F, T, F, F, T, F, F, T, T, T)] # 当要输出的序号超出向量的长度时
[1] 3 6 9 10 NA
> y[y>5 & y<7] # 输出y向量中大于5且小于7的值
[1] 6
> 3/3
[1] 1
> 3/2
[1] 1.5
> 3%2
Error: unexpected input in "3%2"
> y[y<2 | y>7] # 输出y向量中小于2或者大于7的值
[1] 1 8 9 10
%in%在字符串向量中的使用
> x <- c("one", "two", "three", "four", "five") # 创建一个字符串向量x
> "one" %in% x # 判断字符串“one”是否在向量x中,返回一个布尔值
[1] TRUE
> "One" %in% x # 区分大小写
[1] FALSE
> y <- c("one", "two", "three")
> y %in% x # 判断向量y中的元素是否在向量x中
[1] TRUE TRUE TRUE
> x %in% y # 判断向量x中的元素是否在向量y中
[1] TRUE TRUE TRUE FALSE FALSE
> x[x %in% y] # 显示既存在于向量x中,又存在于向量y中的元素
[1] "one" "two" "three"
向量的名字
> x <- c(1, 2, 3, 4, 5)
> y <- c("one", "two", "three", "four", "five") # 创建一个字符串向量
> name(x) # 显示向量x的名字(其实就像是Excel中的表头)
Error in name(x) : could not find function "name"
> name(x) <- y # 将向量y作为向量x的名字
Error in name(x) <- y : could not find function "name<-"
> names(x) # 显示向量x的名字(其实就像是Excel中的表头)
NULL
> names(x) <- y # 将向量y作为向量x的名字
> x
one two three four five
1 2 3 4 5
> x["one"] # 定义了表头之后,就可以以表头来访问向量中的元素
one
1
> x[c("one", "two")]
one two
1 2
> x[c(1, 2)]
one two
1 2
向量的增删
> x <- c(1:5)
> x
[1] 1 2 3 4 5
> x[10] <- 10 # 将向量x的第10个元素赋值为10
> x # 中间未被赋值的将被默认填充为NA
[1] 1 2 3 4 5 NA NA NA NA 10
> append(x, 66, after = 3) # 在向量x的第3个元素后面插入一个值为66的元素
[1] 1 2 3 66 4 5 NA NA NA NA 10
> x
[1] 1 2 3 4 5 NA NA NA NA 10
> rm(x) # 删除向量x
> x
Error: object 'x' not found
> x <- c(1:5) #创建一个数值向量
> x
[1] 1 2 3 4 5
> x <- x[-c(1:3)] # 剔除向量x中的前三个元素
> x
[1] 4 5
向量与向量的运算
> x <- seq(1, 100, by=10)
> x
[1] 1 11 21 31 41 51 61 71 81 91
> y <- c(1:10)
> y
[1] 1 2 3 4 5 6 7 8 9 10
> x+y
[1] 2 13 24 35 46 57 68 79 90 101
> x-y
[1] 0 9 18 27 36 45 54 63 72 81
> x*y
[1] 1 22 63 124 205 306 427 568 729 910
> x/y
[1] 1.000000 5.500000 7.000000 7.750000 8.200000 8.500000 8.714286 8.875000 9.000000 9.100000
> y**x # 开平方
[1] 1.000000e+00 2.048000e+03 1.046035e+10 4.611686e+18 4.547474e+28 4.849688e+39 3.556153e+51 1.316404e+64
[9] 1.966271e+77 1.000000e+91
> x%%y # 整除
[1] 0 1 0 3 1 3 5 7 0 1
> x%%y # 取余
[1] 0 1 0 3 1 3 5 7 0 1
> x%/%y # 整除
[1] 1 5 7 7 8 8 8 8 9 9
两个进行运算的向量的长度必须相等,或者一个为另一个的整数倍:
> x <- c(1:10)
> y <- c(1, 2)
> z <- c(1:3)
> x+y
[1] 2 4 4 6 6 8 8 10 10 12
> x
[1] 1 2 3 4 5 6 7 8 9 10
> y+x
[1] 2 4 4 6 6 8 8 10 10 12
> x+z
[1] 2 4 6 5 7 9 8 10 12 11
Warning message:
In x + z : longer object length is not a multiple of shorter object length
常用运算函数
> x <- c(-5.5, -5.3, 3.2, 3,8)
> abs(x) # 绝对值
[1] 5.5 5.3 3.2 3.0 8.0
> sqrt(x) # 开平方
[1] NaN NaN 1.788854 1.732051 2.828427
Warning message:
In sqrt(x) : NaNs produced
> sqrt(-5.5) # 开平方
[1] NaN
Warning message:
In sqrt(-5.5) : NaNs produced
> sqrt(-5) # 开平方
[1] NaN
Warning message:
In sqrt(-5) : NaNs produced
> sqrt (-5) # 开平方
[1] NaN
Warning message:
In sqrt(-5) : NaNs produced
> sqrt(x[c(3:4)]) # 开根号
[1] 1.788854 1.732051
> log(x[c(3:4)]) # 对数
[1] 1.163151 1.098612
> log10(10) # 对数
[1] 1
> log(16, base = 2) # 对数
[1] 4
> ceiling(x)
[1] -5 -5 4 3 8
> x
[1] -5.5 -5.3 3.2 3.0 8.0
> ceiling(x) # 向上取整
[1] -5 -5 4 3 8
> floor(x) # 向下取整
[1] -6 -6 3 3 8
> trunc(x) # 保留整数部分
[1] -5 -5 3 3 8
> round(x, digits = 2) # 保留两位小数
[1] -5.5 -5.3 3.2 3.0 8.0
> round(x, digits = 3) # 保留两位小数
[1] -5.5 -5.3 3.2 3.0 8.0
> sin(x) # 三角函数
[1] 0.70554033 0.83226744 -0.05837414 0.14112001 0.98935825
> cos(x)
[1] 0.7086698 0.5543743 -0.9982948 -0.9899925 -0.1455000
> x <- c(1:100)
> sum(x) # 求和
[1] 5050
> max()
[1] -Inf
Warning message:
In max() : no non-missing arguments to max; returning -Inf
> max(x) # 求最大值
[1] 100
> min(x) # 求最小值
[1] 1
> range(x) # 求范围(即最大值和最小值)
[1] 1 100
> mean(x) # 中位数
[1] 50.5
> var(x) # 方差
[1] 841.6667
> sd(x) # 标准差
[1] 29.01149
> prod(x) # 求连乘
[1] 9.332622e+157
> median(x) # 平均值
[1] 50.5
> quantile(x) # 四分位数
0% 25% 50% 75% 100%
1.00 25.75 50.50 75.25 100.00
> quantile(x, c(0.2, 0.5, 0.8)) # 自定义分割
20% 50% 80%
20.8 50.5 80.2
知道值反求索引
> x <- c(1:10)
> x
[1] 1 2 3 4 5 6 7 8 9 10
> which.max(x) # 求向量x中最大值的索引
[1] 10
> which.min(x) # 求向量x中最小值的索引
[1] 1
> which(x == 5) # 求向量x中数值等于5
[1] 5
> which(x == 11) # 求向量x中数值等于11的元素的位置
integer(0)
> which(x > 5) # 求向量x中数值大于5的元素的位置
[1] 6 7 8 9 10
矩阵与数组
矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合。向量是一维的,而矩阵是二维的,需要有行和列。
在R软件中,矩阵是有维数的向量,这里的矩阵元素可以是数值型,字符型或者逻辑型,但是每个元素必须都拥有相同的模式,这个和向量一致。
创建矩阵
> x <- matrix(1:100, nrow = 10, ncol = 10) # 创建一个10行10列的矩阵,元素为1到100(默认竖向开始)
> x
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 11 21 31 41 51 61 71 81 91
[2,] 2 12 22 32 42 52 62 72 82 92
[3,] 3 13 23 33 43 53 63 73 83 93
[4,] 4 14 24 34 44 54 64 74 84 94
[5,] 5 15 25 35 45 55 65 75 85 95
[6,] 6 16 26 36 46 56 66 76 86 96
[7,] 7 17 27 37 47 57 67 77 87 97
[8,] 8 18 28 38 48 58 68 78 88 98
[9,] 9 19 29 39 49 59 69 79 89 99
[10,] 10 20 30 40 50 60 70 80 90 100
> y <- matrix(1:20, 4, byrow = T) # # 创建一个4行的矩阵,元素为1到20(横向开始),byrow的参数默认为F
> y
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 6 7 8 9 10
[3,] 11 12 13 14 15
[4,] 16 17 18 19 20
为矩阵的每一维添加名字
> rnames <- c("C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "C10")
> cnames <- c("R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10")
> dimnames(x) <- list(rnames, cnames) # 为矩阵x添加行、列名称
> x
R1 R2 R3 R4 R5 R6 R7 R8 R9 R10
C1 1 11 21 31 41 51 61 71 81 91
C2 2 12 22 32 42 52 62 72 82 92
C3 3 13 23 33 43 53 63 73 83 93
C4 4 14 24 34 44 54 64 74 84 94
C5 5 15 25 35 45 55 65 75 85 95
C6 6 16 26 36 46 56 66 76 86 96
C7 7 17 27 37 47 57 67 77 87 97
C8 8 18 28 38 48 58 68 78 88 98
C9 9 19 29 39 49 59 69 79 89 99
C10 10 20 30 40 50 60 70 80 90 100
矩阵的维数
> x <- c(1:20) # 创建一个向量x
> dim(x) # 向量的维数是0
NULL
> dim(x) <- c(4, 5) # 将向量x的维数改为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
> y <- (1:30) # 创建一个向量y
> dim(y) # 向量y的维数默认是0
NULL
> dim(y) <- c(3, 2, 5) # 将向量y的维数改为3行2列,高度为5(相当于一个长宽高分别为3、2、5的长方体)
> y
, , 1
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
, , 2
[,1] [,2]
[1,] 7 10
[2,] 8 11
[3,] 9 12
, , 3
[,1] [,2]
[1,] 13 16
[2,] 14 17
[3,] 15 18
, , 4
[,1] [,2]
[1,] 19 22
[2,] 20 23
[3,] 21 24
, , 5
[,1] [,2]
[1,] 25 28
[2,] 26 29
[3,] 27 30
array函数
> ?array # 打开array函数的用法
> arr_name_1 <- c("A1", "A2")
> arr_name_2 <- c("B1", "B2", "B3")
> arr_name_3 <- c("C1", "C2", "C3", "C4")
> array(1:24, c(2, 3, 4), dimnames = list(arr_name_1, arr_name_2, arr_name_3)) # 创建一个矩阵,元素为1到24,维数为2*3*4,并为每个维度添加名字
, , 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
访问矩阵中的元素
访问单个元素
> x <- matrix(1:20, 4, 5) # 创建一个矩阵,元素为1到20,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
> x[1, 2] # 矩阵x中位于1行2列的元素
[1] 5
> x[1] # 矩阵x中的第一个元素
[1] 1
> x[6] # 矩阵x中第6个元素
[1] 6
访问多个元素
> x[2, c(2:4)] # 矩阵x中第2行,第2到4个元素
[1] 6 10 14
> x[c(3:4), c(2:4)] # 矩阵x中位于3到4行,2到4列的元素
[,1] [,2] [,3]
[1,] 7 11 15
[2,] 8 12 16
> x[2,] # 矩阵x中第2行的元素
[1] 2 6 10 14 18
> x[,3] # 矩阵x中第3列的元素
[1] 9 10 11 12
> x[-1, 3] # 矩阵x中第三列出去第一个元素的剩下的所有元素
[1] 10 11 12
使用维名称访问元素
> x # 矩阵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
> dimnames(x) <- list(c("B1", "B2", "B3", "B4"), c("A1", "A2", "A3", "A4", "A5")) # 为矩阵的行和列添加名字
> x
A1 A2 A3 A4 A5
B1 1 5 9 13 17
B2 2 6 10 14 18
B3 3 7 11 15 19
B4 4 8 12 16 20
> x["B1", "A4"] # 访问矩阵x中位于B1行A4列的元素
[1] 13
> x["B1", c(2:5)] # 访问矩阵中位于B1行,第2至第5个元素
A2 A3 A4 A5
5 9 13 17
> x["B1",] # 访问矩阵x中B1行的所有元素
A1 A2 A3 A4 A5
1 5 9 13 17
矩阵的运算
> x+1 # 矩阵中所有元素都+1
A1 A2 A3 A4 A5
B1 2 6 10 14 18
B2 3 7 11 15 19
B3 4 8 12 16 20
B4 5 9 13 17 21
> x+x # 矩阵对应的元素相加
A1 A2 A3 A4 A5
B1 2 10 18 26 34
B2 4 12 20 28 36
B3 6 14 22 30 38
B4 8 16 24 32 40
> x*x # 矩阵中所有对应的元素相乘
A1 A2 A3 A4 A5
B1 1 25 81 169 289
B2 4 36 100 196 324
B3 9 49 121 225 361
B4 16 64 144 256 400
矩阵常用的一些内置函数
> sum(x) # 矩阵中所有元素相加
[1] 210
> max(x) # 矩阵x中的最大值
[1] 20
> colSums(x) # 对矩阵中每一列求和
A1 A2 A3 A4 A5
10 26 42 58 74
> rowSums(x) # 对矩阵中每一行求和
B1 B2 B3 B4
45 50 55 60
> colMeans(x) # 对矩阵中每一列求平均值
A1 A2 A3 A4 A5
2.5 6.5 10.5 14.5 18.5
> y <- matrix(1:4, 2, 2)
> y
[,1] [,2]
[1,] 1 3
[2,] 2 4
> z <- matrix(2:5, 2, 2)
> z
[,1] [,2]
[1,] 2 4
[2,] 3 5
> y*z # 矩阵中对应元素相乘(外积)
[,1] [,2]
[1,] 2 12
[2,] 6 20
> y%*%z # 求矩阵(内积)
[,1] [,2]
[1,] 11 19
[2,] 16 28
> diag(x) # 求矩阵对角线元素
[1] 1 6 11 16
> t(x) # 矩阵求转置
B1 B2 B3 B4
A1 1 2 3 4
A2 5 6 7 8
A3 9 10 11 12
A4 13 14 15 16
A5 17 18 19 20
修改矩阵的某一列
> data.frame(women$height*2.54, women$weight) # 这样修改有个问题,会导致列名称变得很长
women.height...2.54 women.weight
1 147.32 115
...
> data.frame(height=women$height*2.54, weight=women$weight) # 修改的时候直接重新指定列名称
height weight
1 147.32 115
...
> ?transform # 上面的修改方式本质上是“重新制造”了一个矩阵,并不是在原矩阵上进行修改,性能不高。
> transform(women, height=height*2.54) # 这才是高效的方式
height weight
1 147.32 115
...
> transform(women, cm=height*2.54) # 你甚至可以新加一列
height weight cm
1 58 115 147.32
...
t()——转置
> head(mtcars)
mpg cyl disp hp drat wt qsec vs am gear
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4
...
> head(t(mtcars))
Mazda RX4 Mazda RX4 Wag Datsun 710 Hornet 4 Drive
mpg 21.00 21.000 22.80 21.400
cyl 6.00 6.000 4.00 6.000
disp 160.00 160.000 108.00 258.000
...
行求和与列求和
> WorldPhones # 一个矩阵
N.Amer Europe Asia S.Amer Oceania Africa Mid.Amer
1951 45939 21574 2876 1815 1646 89 555
1956 60423 29990 4708 2568 2366 1411 733
1957 64721 32510 5230 2695 2526 1546 773
1958 68484 35218 6662 2845 2691 1663 836
1959 71799 37598 6856 3000 2868 1769 911
1960 76036 40341 8220 3145 3054 1905 1008
1961 79831 43173 9053 3338 3224 2005 1076
> rowSums(WorldPhones) # 行求和
1951 1956 1957 1958 1959 1960 1961
74494 102199 110001 118399 124801 133709 141700
> class(WorldPhones) # 为什么它既是矩阵又是数据集???
[1] "matrix" "array"
> colSums(WorldPhones) # 列求和
N.Amer Europe Asia S.Amer Oceania Africa Mid.Amer
467233 240404 43605 19406 18375 10388 5892
> transform(WorldPhones, sum=rowSums(WorldPhones)) # 行求和,并把求和结果添加到最后一列
N.Amer Europe Asia S.Amer Oceania Africa Mid.Amer sum
1951 45939 21574 2876 1815 1646 89 555 74494
1956 60423 29990 4708 2568 2366 1411 733 102199
1957 64721 32510 5230 2695 2526 1546 773 110001
1958 68484 35218 6662 2845 2691 1663 836 118399
1959 71799 37598 6856 3000 2868 1769 911 124801
1960 76036 40341 8220 3145 3054 1905 1008 133709
1961 79831 43173 9053 3338 3224 2005 1076 141700
> cbind(WorldPhones, sum=rowSums(WorldPhones)) # 另一种方式
N.Amer Europe Asia S.Amer Oceania Africa Mid.Amer sum
1951 45939 21574 2876 1815 1646 89 555 74494
1956 60423 29990 4708 2568 2366 1411 733 102199
1957 64721 32510 5230 2695 2526 1546 773 110001
1958 68484 35218 6662 2845 2691 1663 836 118399
1959 71799 37598 6856 3000 2868 1769 911 124801
1960 76036 40341 8220 3145 3054 1905 1008 133709
1961 79831 43173 9053 3338 3224 2005 1076 141700
> rbind(WorldPhones, sum=colSums(WorldPhones)) # 列求和,将求和结果作为新的一行赋值到最后一行
N.Amer Europe Asia S.Amer Oceania Africa Mid.Amer
1951 45939 21574 2876 1815 1646 89 555
1956 60423 29990 4708 2568 2366 1411 733
1957 64721 32510 5230 2695 2526 1546 773
1958 68484 35218 6662 2845 2691 1663 836
1959 71799 37598 6856 3000 2868 1769 911
1960 76036 40341 8220 3145 3054 1905 1008
1961 79831 43173 9053 3338 3224 2005 1076
sum 467233 240404 43605 19406 18375 10388 5892
apply()——自定义操作函数(矩阵&数据集)
> ?apply(array, margin, ...) # 可以进行自定义function
> apply(WorldPhones, MARGIN = 1, FUN = sum())
Error in match.fun(FUN) : 'sum()'不是函数,也不是字符,也不是符號
> apply(WorldPhones, MARGIN = 1, FUN = sum) # MARGIN = 1 行操作
1951 1956 1957 1958 1959 1960 1961
74494 102199 110001 118399 124801 133709 141700
> apply(WorldPhones, MARGIN = 2, FUN = sum) # MARGIN = 2 列操作
N.Amer Europe Asia S.Amer Oceania Africa Mid.Amer
467233 240404 43605 19406 18375 10388 5892
> apply(WorldPhones, MARGIN = 1, FUN = mean)
1951 1956 1957 1958 1959 1960 1961
10642.00 14599.86 15714.43 16914.14 17828.71 19101.29 20242.86
> apply(WorldPhones, MARGIN = 1, FUN = max)
1951 1956 1957 1958 1959 1960 1961
45939 60423 64721 68484 71799 76036 79831
矩阵与向量的排序问题
rev()——使向量、矩阵反序
> ?rev
> letters
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o"
[16] "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
> rev(letters) # 向量的反序
[1] "z" "y" "x" "w" "v" "u" "t" "s" "r" "q" "p" "o" "n" "m" "l"
[16] "k" "j" "i" "h" "g" "f" "e" "d" "c" "b" "a"
> women
height weight
1 58 115
2 59 117
3 60 120
...
> women[rev(row.names(women)),] # 矩阵的反序
height weight
15 72 164
14 71 159
13 70 154
...
注意,使用rev()
函数反序的话,参数只能为矩阵的行名称,如果想使用某一列作为反序的参考,需要使用sort()
函数,后面介绍。
sort()——向量与矩阵的排序
> rivers # 原数据
[1] 735 320 325 392 524 450 1459 135 465 600 330 336 ...
> sort(rivers) # 默认正序
[1] 135 202 210 210 215 217 230 230 233 237 246 250 ...
> sort(rivers, decreasing = T) # 倒序
[1] 3710 2533 2348 2315 1885 1770 1459 1450 1306 1270 1243 1205 ...
> rev(sort(rivers)) # 与上一步作用一致,其余例子可以反推
[1] 3710 2533 2348 2315 1885 1770 1459 1450 1306 1270 1243 1205 ...
> sort(state.name, decreasing = T) # 字符串型向量也是可以滴~
[1] "Wyoming" "Wisconsin" "West Virginia" ...
> sort(women$height) # ?
[1] 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
?:sort()
函数可以对矩阵的某一列进行排序(正序或者逆序),但是却不能对矩阵排序(利用排序的某一列不能去反推整个矩阵的排序)。举个例子:women
数据为15个女人的身高、体重数据,使用sort()
函数只能对这个矩阵数据的某一列数据(相当于一个向量,例如women$height
,相当于单独把这一列拿出来,作为一个向量排序,已经失去了与原来矩阵的关联性)进行排序,并不能将15个女人按照身高的顺序进行排序。使用order()
函数可以解决这个问题。
sort()
函数对矩阵排序的话只有一种情况,就是排序参数是矩阵的行名称,这个时候sort函数是可以的。这是为什么呢?因为矩阵元素的访问方式可以通过每一行的行名称来访问这一行,但是不能通过这一行中的某一个元素来访问这一行。举个栗子:
> mtcars # 原数据
mpg cyl disp hp drat wt qsec vs am gear
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4
...
> mtcars[sort(row.names(mtcars)),] # 按照行排序后的数据
mpg cyl disp hp drat wt qsec vs am gear
AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3
Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3
....
> mtcars[rev(sort(row.names(mtcars))),] # 设置可以结合rev()函数来个逆序
mpg cyl disp hp drat wt qsec vs am gear
Volvo 142E 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4
Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3
...
order()——矩阵自定义排序
为了解决sort()
函数的不足,便有了它。
举个例子:
> ?order
> rivers # 原向量
[1] 735 320 325 392 524 450 1459 135 465 600 330 336 ...
> sort(rivers) # 排序后的向量(正序)
[1] 135 202 210 210 215 217 230 230 233 237 246 250 ...
> order(rivers) # order()函数返回的是排序(正序)后对应的位置(下标)
[1] 8 17 39 108 129 52 36 42 91 117 133 34 56 87 76 ...
> rivers[8] # 举个栗子:order()返回的第一个值是8,就说明rivers向量排序(正序)后,在第1个的元素是原来排在第8个位置的元素
[1] 135
找个矩阵练习下:
> mtcars # 一个矩阵数据
mpg cyl disp hp drat wt qsec vs am gear
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4
...
> order(mtcars$mpg) # 按照矩阵中的mpg列进行排序,排在第一个的是15,就说明原来矩阵第15行对应的mpg值是这一列中最小的。
[1] 15 16 24 7 17 31 14 23 22 29 12 13 11 6 5 10 25 30 1 2 4 ...
> mtcars[order(mtcars$mpg),] # 应为order()函数返回的是排序后原来每一行的下标(原来每一行的行号),这个时候就可以利用order()的返回值来对矩阵进行排序
mpg cyl disp hp drat wt qsec vs am gear
Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3
Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3
Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3
Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3
...
> mtcars[order(mtcars$mpg, decreasing = T),] # 如何逆序?添加参数
mpg cyl disp hp drat wt qsec vs am gear
Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4
Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4
Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4
Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5
...
> mtcars[order(-mtcars$mpg),] # 一个逆序的骚操作,把原来的mpg列值全部变为负数再进行排序的话,原来的最大值就变成了最小值
mpg cyl disp hp drat wt qsec vs am gear
Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4
Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4
Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4
Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5
...
> mtcars[rev(order(mtcars$mpg)),] # 使用rev()函数也可以逆序,原理:order()函数取出排序后的下标后,对下标使用rev()逆序。
mpg cyl disp hp drat wt qsec vs am gear
Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4
Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4
...
小问题:如何根据两列来排序?
> mtcars[order(mtcars$mpg),]
mpg cyl disp hp drat wt qsec vs am gear
Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3
Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3
Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3
Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3
> mtcars[order(mtcars$mpg, mtcars$cyl),] # 当两行的mpg数据一样时,再根据cyl数据来排序
mpg cyl disp hp drat wt qsec vs am gear
Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3
Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3
Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3
...
列表
列表顾名思义就是用来存储很多内容的一个集合,在其他编程语言中列表一般和数组是等同的,但是在R语言中,列表却是R中最复杂的一种数据结构,也是非常重要的一种数据结构。
列表就是一些对象的有序集合。列表中可以存储若干向量、矩阵、数据框,甚至其他列表的组合。
列表特点:
- 在模式上和向量类似,都是一维数据集合。
- 向量只能存储一种数据类型,列表中的对象可以是R中的任何数据结构,甚至列表本身。
创建一个列表
> a <- (1:5)
> b <- matrix(1:20, 4)
> c <- 5
> d <- "This is a string."
> mlist <- list(a, b, c, d) # 定义一个列表
> mlist # 查看该列表
[[1]]
[1] 1 2 3 4 5
[[2]]
[,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
[[3]]
[1] 5
[[4]]
[1] "This is a string."
访问列表中的元素
> mlist[1] # 访问列表中的第一个元素
[[1]]
[1] 1 2 3 4 5
> mlist[c(3, 4)] # 访问列表中第3和第4个元素
[[1]]
[1] 5
[[2]]
[1] "This is a string."
> mlist[[1]] # 访问列表中的第一个元素,注意:此种访问方式和上面的是不同的
[1] 1 2 3 4 5
> class(mlist[1]) # 通过“[]”方式访问的时候,访问的元素还是列表的格式
[1] "list"
> class(mlist[[1]]) # 通过“[[]]”方式访问的时候,访问的元素是该元素本身的格式
[1] "integer"
创建列表时指定元素的名称
> nlist <- list(first=a, second=b, third=c, forth=d) # 可以为列表中每个元素添加名字。就离谱,为啥有的可以不加引号,有的就需要加引号,R中变量的命名太离谱了!!!
> nlist
$first
[1] 1 2 3 4 5
$second
[,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
$third
[1] 5
$forth
[1] "This is a string."
通过列表中元素的名字来访问该元素
> nlist$first # 通过列表内元素的名字访问各个元素
[1] 1 2 3 4 5
> nlist$forth
[1] "This is a string."
> nlist$second
[,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
> nlist$second[1] # 注意:当通过列表内元素的名字来访问元素的时候,不需要使用“[[]]”的方式来进行访问
[1] 1
> nlist$second[1,]
[1] 1 5 9 13 17
> nlist[2] # 返回一个列表,该列表里只有一个元素,就是一个矩阵
$second
[,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
> nlist[2][1] # 返回一个矩阵
$second
[,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
> nlist[[2]][1] # 返回列表中第2个元素(一个矩阵)之中的第一个元素
[1] 1
> nlist[[2]][1, c(3:5)] # 返回列表中第2个元素(一个矩阵)之中的第一行中第3~5个元素
[1] 9 13 17
> class(b)
[1] "matrix" "array"
访问列表中元素时的一个注意点
> class(nlist$second) # 通过列表中元素的名字直接访问元素($)时,可以直接访问到该元素,等同于使用“[[]]”方式访问
[1] "matrix" "array"
> class(nlist[2]) # 通过“[]”访问列表中的元素,访问到的时“披着列表的皮的元素”
[1] "list"
> class(nlist[[2]]) # 想要直接访问到该元素需要使用“[[]]”方式访问
[1] "matrix" "array"
> nlist[2][1][1] # 通过“套娃”的方式来访问是不行的
$second
[,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
删除列表中的元素
> nlist[c(-1, -2)] # 删除列表中第1、第2个元素
$third
[1] 5
$forth
[1] "This is a string."
> nlist[4] <- NULL # 删除列表中第4个元素
> nlist$third <- NULL # 删除列表中名称为“third”的元素
> nlist
$first
[1] 1 2 3 4 5
$second
[,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
lapply()与sapply()
> apply(WorldPhones, MARGIN = 1, FUN = sum) # apply()函数可以应用于矩阵或者数据集数据
1951 1956 1957 1958 1959 1960 1961
74494 102199 110001 118399 124801 133709 141700
> state.center # 但是对于列表型数据的话,apply()函数就不行了
$x
[1] -86.7509 -127.2500 -111.6250 -92.2992 -119.7730 -105.5130
[7] -72.3573 -74.9841 -81.6850 -83.3736 -126.2500 -113.9300
[13] -89.3776 -86.0808 -93.3714 -98.1156 -84.7674 -92.2724
[19] -68.9801 -76.6459 -71.5800 -84.6870 -94.6043 -89.8065
[25] -92.5137 -109.3200 -99.5898 -116.8510 -71.3924 -74.2336
[31] -105.9420 -75.1449 -78.4686 -100.0990 -82.5963 -97.1239
[37] -120.0680 -77.4500 -71.1244 -80.5056 -99.7238 -86.4560
[43] -98.7857 -111.3300 -72.5450 -78.2005 -119.7460 -80.6665
[49] -89.9941 -107.2560
$y
[1] 32.5901 49.2500 34.2192 34.7336 36.5341 38.6777 41.5928
[8] 38.6777 27.8744 32.3329 31.7500 43.5648 40.0495 40.0495
[15] 41.9358 38.4204 37.3915 30.6181 45.6226 39.2778 42.3645
[22] 43.1361 46.3943 32.6758 38.3347 46.8230 41.3356 39.1063
[29] 43.3934 39.9637 34.4764 43.1361 35.4195 47.2517 40.2210
[36] 35.5053 43.9078 40.9069 41.5928 33.6190 44.3365 35.6767
[43] 31.3897 39.1063 44.2508 37.5630 47.4231 38.4204 44.5937
[50] 43.0504
> lapply(state.center, FUN = length) # lapply()函数返回一个list对象
$x
[1] 50
$y
[1] 50
> sapply(state.center, FUN = length) # sapply()函数返回一个向量对象,其两者的作用本质是一样的,都是对list对象应用函数操作
x y
50 50
> class(lapply(state.center, FUN = length)) # 返回列表对象
[1] "list"
> class(sapply(state.center, FUN = length)) # 返回向量对象
[1] "integer"
数据框
数据框是一种表格式的数据结构。数据框旨在模拟数据集,与其他统计软件例如SAS
或者SPSS
中的数据集的概念一致。
数据集通常是由数据构成的一个矩形数组,行表示观测,列表示变量。不同的行业对于数据集的行和列叫法不同。
数据框实际上是一个列表。列表中的元素是向量,这些向量构成数据框的列,每一列必须具有相同的长度,所以数据框是矩形结构,而且数据框的列必须命名。
数据框特点:
- 数据框形状上很像矩阵;
- 数据框是比较规则的列表;
- 矩阵必须为同一数据类型;
- 数据框每一列必须同一类型,每一行可以不同。
> state <- data.frame(state.name, state.region, state.abb, state.area, state.center, state.division, state.x77) # 创建一个数据框
> state[1] # 访问数据框的第一列
state.name
Alabama Alabama
Alaska Alaska
Arizona Arizona
...
> state["Area"] # 访问数据框的“Area”列
Area
Alabama 50708
Alaska 566432
Arizona 113417
Arkansas 51945
...
> state[,"state.abb"] # 访问数据框的“state.abb”列
[1] "AL" "AK" "AZ" "AR" "CA" "CO" "CT" "DE" "FL" "GA" "HI" "ID" "IL" "IN" "IA" "KS" "KY" "LA" "ME" "MD" "MA" "MI" "MN"
> state$Area # 可以像列表一样用“$”访问
[1] 50708 566432 113417 51945 156361 103766 4862 1982 54090 58073 6425 82677 55748 36097 55941 81787
[17] 39650 44930 30920 9891 7826 56817 79289 47296 68995 145587 76483 109889 9027 7521 121412 47831
[33] 48798 69273 40975 68782 96184 44966 1049 30225 75955 41328 262134 82096 9267 39780 66570 24070
[49] 54464 97203
> women
height weight
1 58 115
2 59 117
3 60 120
4 61 123
5 62 126
6 63 129
7 64 132
8 65 135
9 66 139
10 67 142
11 68 146
12 69 150
13 70 154
14 71 159
15 72 164
> plot(women$height, women$weight)
> ?attach
> ?mtcars
> mtcars
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
...
> mtcars$mpg
[1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2
[24] 13.3 19.2 27.3 26.0 30.4 15.8 19.7 15.0 21.4
> attach(mtcars)
> mpg
[1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2
[24] 13.3 19.2 27.3 26.0 30.4 15.8 19.7 15.0 21.4
> detach(mtcars)
> mpg
Error: object 'mpg' not found
R中矩阵与数据框的区别:两者都表示矩形数据类型,这意味着它们用于存储具有行和列的表格数据。这两者的主要区别是,矩阵只能包含一种数据类型,而数据框可以包含多种数据类型。
merge()——数据框的合并
合并一个数据框(或者矩阵)与一个向量的方法:
> x <- data.frame(k1 = c(NA,NA,3,4,5), k2 = c(1,NA,NA,4,5), # 两个矩阵对象
+ data = 1:5)
> y <- data.frame(k1 = c(NA,2,NA,4,5), k2 = c(NA,NA,3,4,5),
+ data = 1:5)
> x # x向量一共也有5列
k1 k2 data
1 NA 1 1
2 NA NA 2
3 3 NA 3
4 4 4 4
5 5 5 5
> y # y向量一共也有5列
k1 k2 data
1 NA NA 1
2 2 NA 2
3 NA 3 3
4 4 4 4
5 5 5 5
> transform(x, demo = y[,'k1']) # 合并一个矩阵与一个向量
k1 k2 data demo
1 NA 1 1 NA
2 NA NA 2 2
3 3 NA 3 NA
4 4 4 4 4
5 5 5 5 5
开始进入正题:
## 在分析之前,首先一点要知道:`merge()`函数取得是交集。首先,x与y有两列完全相同,那么着这两列肯定是交集了,那么必须有的,也就是对应下面的1、2两行;接下来因为是以k1列为参考,
> x[,'k1'] ## 可以看到,除了完全相同的4、5两行,还有x中的两个NA与y中的两个NA对应。2×2也就有了4种自由组合方式。
[1] NA NA 3 4 5
> y[,'k1']
[1] NA 2 NA 4 5
> merge(x, y, by = "k1") ## 合并数据框x、y,以k1列为主参考
k1 k2.x data.x k2.y data.y
1 4 4 4 4 4
2 5 5 5 5 5
3 NA 1 1 NA 1
4 NA 1 1 3 3
5 NA NA 2 NA 1
6 NA NA 2 3 3
## 换成k2列分析下:1、首先看下两个数据框的k2列对应的交集,交集应该为NA NA 4 5;
> x[,'k2']
[1] 1 NA NA 4 5
> y[,'k2']
[1] NA NA 3 4 5
## 那么对应的,4 5 对应的两行完全相同,那么自然是需要的,剩下的各自都有两个NA,又是2×2=4种排列组合。
> merge(x, y, by = "k2")
k2 k1.x data.x k1.y data.y
1 4 4 4 4 4
2 5 5 5 5 5
3 NA NA 2 NA 1
4 NA NA 2 2 2
5 NA 3 3 NA 1
6 NA 3 3 2 2
## incomparables参数用来过滤“关键字”
> merge(x, y, by = "k2", incomparables = NA)
k2 k1.x data.x k1.y data.y
1 4 4 4 4 4
2 5 5 5 5 5
> merge(x, y, by = "k2", incomparables = c(NA, 4))
k2 k1.x data.x k1.y data.y
1 5 5 5 5 5
## 当同时以k1和k2为主参考时,那么必须只有k1与k2都完全一样才能被提取出来
> merge(x, y, by = c("k1", "k2"))
k1 k2 data.x data.y
1 4 4 4 4
2 5 5 5 5
3 NA NA 2 1
因子
R中的变量分类
- 名义型变量(人名之类的,单一性,不连续性)
- 有序型变量(数字)
- 连续型变量(例如:women, men; bad, good, better, best,介于以上两者之间的)
因子,在R中名义型变量和有序性变量称为因子,factor
。这些分类变量的可能值称为一个水平level
,例如good,better,best,都称为一个level
。由这些水平值构成的向量就称为因子。
因子的应用
- 计算频数
- 独立性检验
- 相关性检验
- 方差分析
- 主成分分析
- 因子分析
- ...
连续性变量举例
> mtcars # mtcars数据框
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
...
> mtcars['cyl'] # mtcars数据框中的cyl列(发动机缸数)就是连续性变量
cyl
Mazda RX4 6
Mazda RX4 Wag 6
Datsun 710 4
Hornet 4 Drive 6
...
> mtcars$cyl # 因为这一列的数据中只有4、6、8
[1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4
> table(mtcars$cyl) # 对这一列进行数据透析
4 6 8
创建因子
> week <- factor(c("Mon", "Fri", "Thu", "Wed", "Mon", "Fri")) # 创建一个因子
> week # 查看该因子
[1] Mon Fri Thu Wed Mon Fri
Levels: Fri Mon Thu Wed
> week <- factor(c("Mon", "Fri", "Thu", "Wed", "Mon", "Fri"), levels = c("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")) # 创建因子时指定levels,levels中的值不能重复,重复的话会报错
> week # 查看该因子
[1] Mon Fri Thu Wed Mon Fri
Levels: Mon Tue Wed Thu Fri Sat Sun
> week <- factor(c("Mon", "Fri", "Thu", "Wed", "Mon", "Fri"), levels = c("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"), ordered = T) # 创建因子,并对levels进行一个排序
> week
[1] Mon Fri Thu Wed Mon Fri
Levels: Mon < Tue < Wed < Thu < Fri < Sat < Sun
因子绘图举例
> demo_cyl <- factor(mtcars$cyl)
> plot(demo_cyl) # 绘制图2,观察把“mtcars$cyl”经过因子变换前后绘制图有什么区别
> plot(mtcars$cyl) # 绘制图1
> mtcars$cyl
[1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4
> demo_cyl
[1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4
Levels: 4 6 8
> x <- 1:100
> cut(x, c(seq(0, 100, 10)))
[1] (0,10] (0,10] (0,10] (0,10] (0,10] (0,10] (0,10]
[8] (0,10] (0,10] (0,10] (10,20] (10,20] (10,20] (10,20]
[15] (10,20] (10,20] (10,20] (10,20] (10,20] (10,20] (20,30]
[22] (20,30] (20,30] (20,30] (20,30] (20,30] (20,30] (20,30]
[29] (20,30] (20,30] (30,40] (30,40] (30,40] (30,40] (30,40]
[36] (30,40] (30,40] (30,40] (30,40] (30,40] (40,50] (40,50]
[43] (40,50] (40,50] (40,50] (40,50] (40,50] (40,50] (40,50]
[50] (40,50] (50,60] (50,60] (50,60] (50,60] (50,60] (50,60]
[57] (50,60] (50,60] (50,60] (50,60] (60,70] (60,70] (60,70]
[64] (60,70] (60,70] (60,70] (60,70] (60,70] (60,70] (60,70]
[71] (70,80] (70,80] (70,80] (70,80] (70,80] (70,80] (70,80]
[78] (70,80] (70,80] (70,80] (80,90] (80,90] (80,90] (80,90]
[85] (80,90] (80,90] (80,90] (80,90] (80,90] (80,90] (90,100]
[92] (90,100] (90,100] (90,100] (90,100] (90,100] (90,100] (90,100]
[99] (90,100] (90,100]
10 Levels: (0,10] (10,20] (20,30] (30,40] (40,50] (50,60] ... (90,100]
> plot(cut(x, seq(0, 100, 10))) # 绘制图3,使用cut()函数可以对数值型连续性变量进行转化为因子
> state.region # R内置因子型数据
[1] South West West South
[5] West West Northeast South
...
Levels: Northeast South North Central West
> plot(state.region) # 绘制图4
[photos]
[/photos]
table()&tapply()——针对含有因子类型数据的操作
> state # state 数据集型对象
state.name state.region state.abb state.area
Alabama Alabama South AL 51609
Alaska Alaska West AK 589757
Arizona Arizona West AZ 113909
...
> tapply(state.name, state.division, FUN = length) # 第二个参数要填入因子数据(连续型变量)
New England Middle Atlantic South Atlantic
6 3 8
East South Central West South Central East North Central
4 4 5
West North Central Mountain Pacific
7 8 5
> table(state.division) # state.division是连续型变量,可以作为因子来操作
state.division
New England Middle Atlantic South Atlantic
6 3 8
East South Central West South Central East North Central
4 4 5
West North Central Mountain Pacific
7 8 5
缺失数据
缺失数据分类
统计学家通常将缺失数据分为三类。它们都用概率术语进行描述,但思想都非常直观。我们将用sleep研究中对做梦时长的测量(有12个动物有缺失值)来依次阐述三种类型。
完全随机缺失:若某变量的缺失数据与其他任何观测或未观测变量都不相关,则数据为完全随机缺失(MCAR)。若12个动物的做梦时长值缺失不是由于系统原因,那么可认为数据是(MCAR)。注意,如果每个有缺失值的变量都是MCAR,那么可以将数据完整的实例看做是对更大数据集的一个简单随机抽样。
随机缺失:若某变量上的缺失数据与其他观测变量相关,与它自己的未观测值不相关,则数据为随机缺失(MAR)。例如,体重较小的动物更可能有做梦时长的缺失值(可能因为较小的动物较难观察)“缺失”与动物的做梦时长无关,那么该数据就可以认为是MAR。此时,一旦你控制了体重变量,做梦时长数据的缺失与出现将是随机的。
非随机缺失:若缺失数据不属于MCAR或MAR,则数据为非随机缺失(NMAR)。例如,做梦时长越短的动物也更可能有做梦数据的缺失(可能由于难以测量时长较短的事件),那么数据可认为是NMAR。
为何会出现缺失数据?
- 机器断电,设备故障导致某个测量值发生了丢失。
- 测量根本没有发生,例如在做调查问卷时,有些问题没有回答,或者有些问题是无效的回答等。
在R中,NA代表缺失值,NA是不可用,not available的简称,用来存储缺失信息。
这里缺失值NA表示没有,但注意没有并不一定就是0,NA是不知道是多少,也能是0,也可能是任何值,缺失值和值为零是完全不同的。
> 1+NA # NA与数值相加仍为NA
[1] NA
> 0 == NA # NA是不等于0
[1] NA
> x <- c(1, NA, 2:10, NA) # 创建一个带有缺失值的数值型变量
> x
[1] 1 NA 2 3 4 5 6 7 8 9 10 NA
> sum(x) # 元素中含有NA,那么结果中也是NA
[1] NA
> sum(x, na.rm = T) # 计算的时候去除NA
[1] 55
> mean(x)
[1] NA
> mean(x, na.rm = T)
[1] 5.5
> is.na(x) # 判断是否含有NA
[1] FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
矩阵中含有缺失值的处理
> library(VIM) # 载入VIM包,需要使用里面的sleep矩阵
> sleep # 一些动物睡眠的数据
BodyWgt BrainWgt NonD Dream Sleep Span Gest Pred Exp Danger
1 6654.000 5712.00 NA NA 3.3 38.6 645.0 3 5 3
2 1.000 6.60 6.3 2.0 8.3 4.5 42.0 3 1 3
3 3.385 44.50 NA NA 12.5 14.0 60.0 1 1 1
4 0.920 5.70 NA NA 16.5 NA 25.0 5 2 3
5 2547.000 4603.00 2.1 1.8 3.9 69.0 624.0 3 5 4
...
> length(sleep) # 显示矩阵的列数
[1] 10
> length(row.names(sleep)) # 显示矩阵的行数
[1] 62
> length(row.names(na.omit(sleep))) # 去除矩阵中含有缺失值的行
[1] 42
R中缺失值得处理方式
其他缺失数据
- 缺失数据
NaN
代表不可能的值; Inf
表示无穷,分为正无穷Inf
和负无穷Inf
,代表无穷大或者无穷小,是不可能的值。
NA
是存在的值,但是不知道是多少,
> 1/0
[1] Inf
> 0/0
[1] NaN
> -1/0
[1] -Inf
> is.nan(0/0)
[1] TRUE
> is.infinite(-1/0)
[1] TRUE
字符串
nchar()——字符串长度
> nchar("Hello, world.") # 统计字符串中字符数(字符串的长度),包含标点符号和空格
[1] 13
> month.name # R中内置的一个字符串
[1] "January" "February" "March" "April" "May" "June" "July"
[8] "August" "September" "October" "November" "December"
> class(month.name) # 它的类型是一个字符串向量
[1] "character"
> nchar(month.name) # 返回字符串向量中每一个字符串的长度
[1] 7 8 5 5 3 4 4 6 9 7 8 8
> length(month.name) # 返回字符串向量的长度(即内部元素个数)
[1] 12
> length("Hello, world.") # 返回元素个数
[1] 1
> nchar(1:10) # 对数值型向量使用,会默认将每一个数值转化为字符串,再查看字符个数
[1] 1 1 1 1 1 1 1 1 1 2
paste()——粘合字符串
> x <- c("Everybody", "Loves", "Money") # 创建一个字符串向量x
> paste("Everybody", "Loves", "Money") # 将几个字符串变量合并为一个字符串(默认的分隔符是空格)
[1] "Everybody Loves Money"
> paste("Everybody", "Loves", "Money", sep = "-") # sep参数更改默认分隔符
[1] "Everybody-Loves-Money"
> paste(x, "1111", "2222", sep = "_") # 一个举例
[1] "Everybody_1111_2222" "Loves_1111_2222" "Money_1111_2222"
substr()——截取字符串
> substr(month.name, start = 1, stop = 3) # 截取字符串向量中每个元素的前三位
[1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
> substr(month.name, 1, 3)
[1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
toupper(), tolower()——字符串的大小写转换
> toupper(substr(month.name, 1, 3))
[1] "JAN" "FEB" "MAR" "APR" "MAY" "JUN" "JUL" "AUG" "SEP" "OCT" "NOV" "DEC"
> tolower(substr(month.name, 1, 3))
[1] "jan" "feb" "mar" "apr" "may" "jun" "jul" "aug" "sep" "oct" "nov" "dec"
gsub()——R中正则表达式的使用
> ?gsub()
> gsub("^(\\w)", "\\U\\1", tolower(month.name), perl = T)
[1] "January" "February" "March" "April" "May" "June" "July"
[8] "August" "September" "October" "November" "December"
> gsub("^(\\w)", "\\U\\1", substr(tolower(month.name), 1, 3), perl = T)
[1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
grep(), match()——查找字符串中的元素
> x <- c("b", "A", "ABC", "asasABC")
> grep("A+", x)
[1] 2 3 4
> grep("A+", x, fixed = T)
integer(0)
> grep("A+", x, fixed = F)
[1] 2 3 4
> x <- c("b", "A", "ABC", "asasABC", "A+")
> grep("A+", x, fixed = T)
[1] 5
> match("A", x)
[1] 2
> "A" %in% x
[1] TRUE
strsplit()——拆分字符串
> z <- paste("Everybody", "Loves", "Money", sep = "_") # 创建一个字符串向量
> z
[1] "Everybody_Loves_Money"
> strsplit(z, "_") # 分解字符串向量, 注意:分解出来的是列表对象([[]]),并不是向量
[[1]]
[1] "Everybody" "Loves" "Money"
>
> strsplit(z, "_")[[1]] # 取出列表中的向量
[1] "Everybody" "Loves" "Money"
> class(strsplit(z, "_"))
[1] "list"
> strsplit(c(z, z), "_") # 这一步就可以解释为什么分解出来的是列表对象了,因为该函数可以同时分解多个字符串
[[1]]
[1] "Everybody" "Loves" "Money"
[[2]]
[1] "Everybody" "Loves" "Money"
outer()——解释起来很麻烦,自己看例子
> face <- 1:13 # 创建一个数值型向量(代表扑克牌1到13)
> suit <- c("spades", "clubs", "hearts", "diamonds") # 创建一个字符串变量(代表扑克牌的4中花色)
> outer(suit, face, FUN = paste, sep = "_") # 对扑克牌的数字与花色进行一一拼装(sep默认为空格),返回的是一个矩阵对象
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] "spades_1" "spades_2" "spades_3" "spades_4" "spades_5" "spades_6"
[2,] "clubs_1" "clubs_2" "clubs_3" "clubs_4" "clubs_5" "clubs_6"
[3,] "hearts_1" "hearts_2" "hearts_3" "hearts_4" "hearts_5" "hearts_6"
[4,] "diamonds_1" "diamonds_2" "diamonds_3" "diamonds_4" "diamonds_5" "diamonds_6"
[,7] [,8] [,9] [,10] [,11] [,12]
[1,] "spades_7" "spades_8" "spades_9" "spades_10" "spades_11" "spades_12"
[2,] "clubs_7" "clubs_8" "clubs_9" "clubs_10" "clubs_11" "clubs_12"
[3,] "hearts_7" "hearts_8" "hearts_9" "hearts_10" "hearts_11" "hearts_12"
[4,] "diamonds_7" "diamonds_8" "diamonds_9" "diamonds_10" "diamonds_11" "diamonds_12"
[,13]
[1,] "spades_13"
[2,] "clubs_13"
[3,] "hearts_13"
[4,] "diamonds_13"
R界大佬:Hadley Wickham
日期和时间
- 对时间序列的描述;
- 利用前面的结果进行预测。
R中专门处理时间和日期的包:TimeSeries(中科大镜像)。
> sunspots # R内置太阳黑子数据
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
1749 58.0 62.6 70.0 55.7 85.0 83.5 94.8 66.3 75.9 75.5 158.6 85.2
1750 73.3 75.9 89.2 88.3 90.0 100.0 85.4 103.0 91.2 65.7 63.3 75.4
1751 70.0 43.5 45.3 56.4 60.7 50.7 66.3 59.8 23.5 23.2 28.5 44.0
[ reached getOption("max.print") -- omitted 152 rows ]
> presidents # R内置总统支持率数据
Qtr1 Qtr2 Qtr3 Qtr4
1945 NA 87 82 75
1946 63 50 43 32
1947 35 60 54 55
...
> class(sunspots) # 两者的数据类型都是时间序列
[1] "ts"
> class(presidents)
[1] "ts"
> airquality # R内置空气质量数据
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
...
> class(airquality) # 该数据的类型时数据框
[1] "data.frame"
> airquality$Wind # 数据框型数据可以使用$进行访问
[1] 7.4 8.0 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 6.9 9.7 9.2 10.9 13.2 11.5 12.0
...
Sys.Date()——显示当前系统日期
> Sys.Date() # 显示当前时间
[1] "2022-04-16"
> class(Sys.Date())
[1] "Date"
as.Date()——将字符串转换为时间类型数据
> date_time <- "2022-04-16" # 创建一个字符串
> as.Date(date_time, format = "%Y-%m-%d") # 将字符串转换为时间格式数据
[1] "2022-04-16"
> class(as.Date(date_time, format = "%Y-%m-%d"))
[1] "Date"
> class(date_time)
[1] "character"
> ?strftime
> seq(as.Date("2022-01-01"), as.Date("2022-04-16"), by=5) # 创建一个时间序列
[1] "2022-01-01" "2022-01-06" "2022-01-11" "2022-01-16" "2022-01-21" "2022-01-26"
[7] "2022-01-31" "2022-02-05" "2022-02-10" "2022-02-15" "2022-02-20" "2022-02-25"
[13] "2022-03-02" "2022-03-07" "2022-03-12" "2022-03-17" "2022-03-22" "2022-03-27"
[19] "2022-04-01" "2022-04-06" "2022-04-11" "2022-04-16"
> class(as.Date("2022-01-01"))
[1] "Date"
> as.Date("2022-01-01")
[1] "2022-01-01"
> class(as.Date(date_time))
[1] "Date"
> as.Date("2022_01_01")
Error in charToDate(x) : 字符串的格式不够标准明确
> as.Date("2022_01_01", format = "%Y_%m_%d")
[1] "2022-01-01"
ts()——生成时间序列
> ?ts
> sales <- round(runif(48, min = 50, max = 100)) # 生成一个随机整数数值序列
> sales
[1] 89 65 93 85 96 55 59 76 51 52 95 70 75 80 88 59 73 85 81 73 61 81 86 91 71 80
[27] 73 96 58 81 66 78 71 51 64 85 81 75 95 58 99 97 63 88 70 64 79 72
> ts(sales, start = c(2010, 5), end = c(2014, 4), frequency = 12) # 参数为12时,以月份为频率
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2010 89 65 93 85 96 55 59 76
2011 51 52 95 70 75 80 88 59 73 85 81 73
2012 61 81 86 91 71 80 73 96 58 81 66 78
2013 71 51 64 85 81 75 95 58 99 97 63 88
2014 70 64 79 72
> ts(sales, start = c(2010, 5), end = c(2014, 4), frequency = 4) # 参数为4时,以季度为频率
Qtr1 Qtr2 Qtr3 Qtr4
2011 89 65 93 85
2012 96 55 59 76
2013 51 52 95 70
2014 75 80 88 59
> ts(sales, start = c(2010, 5), end = c(2014, 4), frequency = 1) # 参数为1时,以年为频率
Time Series:
Start = 2014
End = 2017
Frequency = 1
[1] 89 65 93 85
获取数据
获取途径
- 利用键盘来输入数据;
- 通过读取存储在外部文件上的数据;
- 通过访问数据库系统来获取数据。
键盘输入(看看就行,谁用谁SB)
> patientID <- c(1, 2, 3, 4) # 创建数据
> admdate <- c("10/15/2009","11/01/2009","10/21/2009","10/28/2009")
> age <- c(25, 34, 28, 52)
> diabetes <- c("Type1", "Type2", "Type1", "Type1")
> status <- c("Poor", "Improved", "Excellent", "Poor")
> patient_data <- data.frame(patientID, admdate, age, diabetes, status)
> patient_data
patientID admdate age diabetes status
1 1 10/15/2009 25 Type1 Poor
2 2 11/01/2009 34 Type2 Improved
3 3 10/21/2009 28 Type1 Excellent
4 4 10/28/2009 52 Type1 Poor
> admdate_ts <- as.Date(admdate, format = "%m/%d/%Y") # 将admdate数据转化为时间序列,方便后续操作
> patient_data_2 <- data.frame(patientID, admdate_ts, age, diabetes, status) # 这个是升级版,时间不再是字符串,而是Date格式数据
> patient_data_2
patientID admdate_ts age diabetes status
1 1 2009-10-15 25 Type1 Poor
2 2 2009-11-01 34 Type2 Improved
3 3 2009-10-21 28 Type1 Excellent
4 4 2009-10-28 52 Type1 Poor
> class(patient_data_2$admdate_ts)
[1] "Date"
read()——读取文件(重点)
> getwd() # 读取文件之前可以先查看下R的工作目录
[1] "C:/Users/myxc/Documents"
> setwd("D:/R") # 设置R的工作目录
> getwd() # 查看R的工作目录已经被修改
[1] "D:/R"
> date_demo <- read.table("./RData/input.txt") # 读取txt文件
> date_demo
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
4 18 313 11.5 62 5 4
...
> head(date_demo) # 查看读取数据框的前五行
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
4 18 313 11.5 62 5 4
5 NA NA 14.3 56 5 5
6 28 NA 14.9 66 5 6
> tail(date_demo) # 查看读取数据框的后五行
Ozone Solar.R Wind Temp Month Day
148 14 20 16.6 63 9 25
149 30 193 6.9 70 9 26
150 NA 145 13.2 77 9 27
151 14 191 14.3 75 9 28
152 18 131 8.0 76 9 29
153 20 223 11.5 68 9 30
> head(date_demo, n = 10) # 查看读取数据框的前10行
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
4 18 313 11.5 62 5 4
5 NA NA 14.3 56 5 5
6 28 NA 14.9 66 5 6
7 23 299 8.6 65 5 7
8 19 99 13.8 59 5 8
9 8 19 20.1 61 5 9
10 NA 194 8.6 69 5 10
几个参数注意下:
nrows
:读取文件的多少行;skip
:跳过文件的前几行;na.strings
:文件中NA数据的表示。sep
:读取的文件每一行中是用什么进行分割的,默认为空格;header
:读取的文件中是否包含数据头。
查看帮助
> help(package="foreign")
> RSiteSearch("Origin") # 使用在线搜索来满足你足够变态的需求
A search query has been submitted to http://search.r-project.org
计算结果应很快就在瀏覽器里打开
读取剪切板
x <- read.table("clipboard") # 方法一
x <- readClipboard() # 方法二
读取压缩文件
x <- read.table(gzfile("input.txt.gz"))
数据库
谁爱学谁学,反正我不学。
写入文件
写入文件的包
> help(package="foreign")
常用的几个命令
> ?write # 写入文件使用的函数
> rivers # R中自带的一个数值型向量
[1] 735 320 325 392 524 450 1459 135 465 600 330 336 280 315 870
...
> class(rivers)
[1] "numeric"
> cat(rivers) # 该函数直接将要写入的文件显示在终端里
735 320 325 392 524 450 1459 135 465 600 330 336 280 315 870 906 202 329 290 1000 600 505 1450 840 ...
> getwd() # 查看R工作目录
[1] "C:/Users/myxc/Documents"
> setwd("D:/R")
> getwd()
[1] "D:/R"
> write(rivers, file = "demo.txt", ncolumns = 10,sep = "-") # 写入文件,一行10个元素,每行元素之间的分隔符为“-”(默认为空格)
> # 注意:R不会创建新的目录
> table_demo <- read.table("./RData/input.txt", header = T)
> head(table_demo)
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
4 18 313 11.5 62 5 4
5 NA NA 14.3 56 5 5
6 28 NA 14.9 66 5 6
> write.table(table_demo, "./new_input.txt") # 写入文件
> write.table(table_demo, "./new_input.csv", sep = ",") # 写入文件,每一行的分隔符使用“,”
> write.table(table_demo, "./new_input.csv", sep = ",", row.names = F) # 写入文件时不要R添加序号
> write.table(table_demo, "./new_input.txt", quote = F) # 写入文件时,去掉每一个变量的引号
> write.table(table_demo, "./new_input.txt", quote = F, na = "?") # 写入的时候NA值用其他代替
> write.table(mtcars, gzfile("mtcars.txt.gz")) # 写入文件直接压缩
写入Excel文件
这一节就是辣鸡,我用个R还要装个Java环境?脱裤子放屁,Python真香!
> install.packages("XLConnect") # R中操作xlsx文件的包(需要Java环境)
> library(XLConnect) # 载入包
> excelTable <- loadWorkbook("./RData/data.xlsx") # 打开xlsx文件
> readWordsheet(excelTable, 1) # 读取文件中的第一个表
#Two step Read Excel File
ex <- loadWorkbook ("data.xlsx")
edata <- readWorksheet(ex,1)
head(edata)
edata <- readWorksheet(ex,1,startRow=0,starCol=0,endRow=50,endCol=3)
#One step Read Excel File
readWorksheetFromFile ("data.xlsx",1,startRow=0,starCol=0,
endRow=50,endCol=3,header=TRUE)
#Four step Wtire Excel File
wb <- loadWorkbook("file.xlsx",create=TRUE)
createSheet(wb,"Sheet 1")
writeWorksheet(wb,data=mtcars,sheet = "Sheet 1")
saveWorkbook()
#One step Wtire Excel File
writeWorksheetToFile("file.xlsx",data = mtcars,sheet = "Sheet 1")
vignette("XLConnect")
#Packages xlsx
install.packages("xlsx")
library(xlsx)
rdata <- read.xlsx("data.xlsx",n=1,startRow = 1,endRow = 100)
write.xlsx(rdata,file = "rdata.xlsx",sheetName = "Sheet 1",append = F)
help(package="xlsx")
读写R格式文件
存储为R文件会有很多优势,R会对存储为内部文件格式的数据进行自动压缩处理,并且会存储所有与待存储对象相关的R元数据。如果数据中包含了因子,日期和时间或者类的属性等信息。
> saveRDS(iris, "./demo.RDS") # 保存R中的变量到R专用的数据格式中
> getwd()
[1] "D:/R"
> input_iris <- readRDS("./demo.RDS") # 读取保存的变量
> head(input_iris) # 和原来的一毛一样
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
> load("./RData/.RData") # 加载R文件
> save(iris, iris3, file = "c:/Users/myxc/Desktop/demo.Rdata") # 保存R工程文件
> save.image() # 保存当前R工程文件
数据转换
> mtcars
mpg cyl disp hp drat wt qsec vs am gear
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4
...
> is.data.frame(mtcars) # 判断数据是否为数据框类型
[1] TRUE
> state.x77
Population Income Illiteracy Life Exp Murder
Alabama 3615 3624 2.1 69.05 15.1
Alaska 365 6315 1.5 69.31 11.3
Arizona 2212 4530 1.8 70.55 7.8
...
> is.data.frame(state.x77) # 判断数据是否为数据框类型
[1] FALSE
> is.data.frame(as.data.frame(state.x77)) # 强制转换数据类型
[1] TRUE
> is.data.frame(data.frame(state.x77))
[1] TRUE
> as.matrix(data.frame(state.x77, state.region))
Population Income Illiteracy Life.Exp Murder
Alabama " 3615" "3624" "2.1" "69.05" "15.1"
Alaska " 365" "6315" "1.5" "69.31" "11.3"
Arizona " 2212" "4530" "1.8" "70.55" " 7.8"
...
> methods(is)
[1] is.array is.atomic
[3] is.call is.character
...
see '?methods' for accessing help and source code
Warning message:
In .S3methods(generic.function, class, envir) :
function 'is' appears not to be S3 generic; found functions that look like S3 methods
> methods(s3)
Error in methods(s3) : object 's3' not found
> methods(is)
[1] is.array is.atomic
[3] is.call is.character
...
see '?methods' for accessing help and source code
Warning message:
In .S3methods(generic.function, class, envir) :
function 'is' appears not to be S3 generic; found functions that look like S3 methods
> methods(as)
[1] as.array as.array.default
[3] as.call as.character
[5] as.character.condition as.character.Date
...
see '?methods' for accessing help and source code
Warning message:
In .S3methods(generic.function, class, envir) :
function 'as' appears not to be S3 generic; found functions that look like S3 methods
> x <- state.abb
> x
[1] "AL" "AK" "AZ" "AR" "CA" "CO" "CT" "DE" "FL" "GA" "HI" "ID"
..
> dim(x) <- c(5, 10)
> x
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] "AL" "CO" "HI" "KS" "MA" "MT" "NM" "OK" "SD" "VA"
...
> state_demo <- data.frame(state.region, state.x77)
> state_demo$Income
[1] 3624 6315 4530 3378 5114 4884 5348 4809 4815 4091 4963 4119
...
> unname(state["Nevada", ]) # 不显示数据框的表头
Nevada Nevada West NV 110540 -116.851 39.1063 Mountain 590 5149
Nevada 0.5 69.03 11.5 65.2 188 109889
数据的中心化与标准化
数据中心化,是指数据集中的各项数据减去数据集的均值。
数据标准化,是指在中心化之后在除以数据集的标准差,即数据集中的各项数据减去数据集的均值再除以数据集的标准差。
中心化与标准化的目的就是为了让一组数据更加地向中心靠拢。
参考网络链接:数据什么时候需要做中心化和标准化处理?
举个例子
> state.x77 # 数据框型&矩阵型对象(有行列名称,可以绘制热图)
Population Income Illiteracy Life Exp Murder
Alabama 3615 3624 2.1 69.05 15.1
Alaska 365 6315 1.5 69.31 11.3
Arizona 2212 4530 1.8 70.55 7.8
...
> heatmap(state.x77)
但是可以看出,state.x77[,'Population']
、state.x77[,'Income']
与state.x77[,'Illiteracy']
等列的数据差值是很大的,如果这个时候进行热图的绘制并没有什么意义,绘制出来的图形颜色对比太模糊。
出现这种情况,我们就要对数据进行中心化与标准化,先讲解下其基本流程:
> x <- c(1:6) # 创建一个数值型向量
> x
[1] 1 2 3 4 5 6
> x_mean <- x-mean(x) # 计算向量x的平均值,然后用向量x中的每个元素都减去平均值
> x_mean # 如果发现这个时候新的向量差值还是很大,那么就可以再次计算标准差
[1] -2.5 -1.5 -0.5 0.5 1.5 2.5
> x_sd <- x_mean/sd(x) # 经历了除以标准差之后,数据之间的差异性就明显减小了,更加收拢。
> x_sd
[1] -1.3363062 -0.8017837 -0.2672612 0.2672612 0.8017837
[6] 1.3363062
scale()——直接进行中心化与标准化
> scale(x)
[,1]
[1,] -1.3363062
[2,] -0.8017837
[3,] -0.2672612
[4,] 0.2672612
[5,] 0.8017837
[6,] 1.3363062
attr(,"scaled:center")
[1] 3.5
attr(,"scaled:scale")
[1] 1.870829
> class(scale(x))
[1] "matrix" "array"
> mean(x)
[1] 3.5
> sd(x)
[1] 1.870829
> scale(x, center = T, scale = T)
[,1]
[1,] -1.3363062
[2,] -0.8017837
[3,] -0.2672612
[4,] 0.2672612
[5,] 0.8017837
[6,] 1.3363062
attr(,"scaled:center")
[1] 3.5
attr(,"scaled:scale")
[1] 1.870829
> ?scale
> scale(state.x77) # 进行中心化与标准化
Population Income Illiteracy Life Exp
Alabama -0.14143156 -1.32113867 1.525758 -1.362193670
Alaska -0.86939802 3.05824562 0.541398 -1.168509784
Arizona -0.45568908 0.15330286 1.033578 -0.244786635
...
attr(,"scaled:center")
Population Income Illiteracy Life Exp Murder HS Grad
4246.4200 4435.8000 1.1700 70.8786 7.3780 53.1080
Frost Area
104.4600 70735.8800
attr(,"scaled:scale")
Population Income Illiteracy Life Exp Murder
4.464491e+03 6.144699e+02 6.095331e-01 1.342394e+00 3.691540e+00
HS Grad Frost Area
8.076998e+00 5.198085e+01 8.532730e+04
> heatmap(scale(state.x77))
经过中心化与标准化再绘制的热图就非常具有对比性,每一列数据的差异性都得到了很好的提现。
几个包的学习
reshape2()
这人讲的太拉了,好歹也是学过好几门编程语言的人,听的迷迷糊糊,看评论好多也都说不行的。
> install.packages("reshape2") # 安装包
> library(reshape2) # 载入包
> class(airquality) # 查看airquality数据框
[1] "data.frame"
> head(airquality)
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
4 18 313 11.5 62 5 4
5 NA NA 14.3 56 5 5
6 28 NA 14.9 66 5 6
> names(airquality) <- tolower(names(airquality)) # 将数据框的列名称全部变成小写
> head(airquality)
ozone solar.r wind temp month day
1 41 190 7.4 67 5 1
...
> melt(airquality) # 会将数据框“融化”
variable value
1 ozone 41.0
2 ozone 36.0
...
154 solar.r 190.0
155 solar.r 118.0
...
307 wind 7.4
308 wind 8.0
...
460 temp 67.0
461 temp 72.0
... # 后面还会有 month、day等,将一个数据框中的数据全部“融化”成一个个单元格
> class(aql) # 还是数据框格式
[1] "data.frame"
> melt(airquality, id.vars = c("month")) # 固定month这一列,然后将其他单元格全部“融化”
month variable value
1 5 ozone 41.0
2 5 ozone 36.0
...
154 5 solar.r 190.0
155 5 solar.r 118.0
...
307 5 wind 7.4
308 5 wind 8.0
...
[ reached 'max' / getOption("max.print") -- omitted 432 rows ]
> dcast(aql, month, ~variable) # 根本没看懂~ 讲的是个啥东西!
Error in is.formula(formula) : object 'month' not found
> dcast(aql, month ~variable)
Error in FUN(X[[i]], ...) : object 'month' not found
> dcast(aql, month+day ~variable)
Error in FUN(X[[i]], ...) : object 'month' not found
tidyr()
> install.packages("tidyr") # 安装包
> library(tidyr) # 载入包
> head(mtcars)
mpg cyl disp hp drat wt qsec vs am gear
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4
...
> class(mtcars)
[1] "data.frame"
> mtcars[1:10,1:3] # 截取mtcar数据框中1~10行,1~3列的元素
mpg cyl disp
Mazda RX4 21.0 6 160.0
Mazda RX4 Wag 21.0 6 160.0
Datsun 710 22.8 4 108.0
Hornet 4 Drive 21.4 6 258.0
Hornet Sportabout 18.7 8 360.0
Valiant 18.1 6 225.0
Duster 360 14.3 8 360.0
Merc 240D 24.4 4 146.7
Merc 230 22.8 4 140.8
Merc 280 19.2 6 167.6
> tdata <- mtcars[1:10,1:3]
> tdata <- data.frame(name=rownames(tdata),tdata) # 将tdata中的行名称添加到数据框中作为一列
> tdata
name mpg cyl disp
Mazda RX4 Mazda RX4 21.0 6 160.0
Mazda RX4 Wag Mazda RX4 Wag 21.0 6 160.0
Datsun 710 Datsun 710 22.8 4 108.0
Hornet 4 Drive Hornet 4 Drive 21.4 6 258.0
Hornet Sportabout Hornet Sportabout 18.7 8 360.0
Valiant Valiant 18.1 6 225.0
Duster 360 Duster 360 14.3 8 360.0
Merc 240D Merc 240D 24.4 4 146.7
Merc 230 Merc 230 22.8 4 140.8
Merc 280 Merc 280 19.2 6 167.6
> gather(tdata,key = "Key",value = "Value",cyl,disp,mpg) # 和resharp2中的merge()差不多
name Key Value
1 Mazda RX4 cyl 6.0
2 Mazda RX4 Wag cyl 6.0
...
11 Mazda RX4 disp 160.0
12 Mazda RX4 Wag disp 160.0
...
21 Mazda RX4 mpg 21.0
22 Mazda RX4 Wag mpg 21.0
...
> gather(tdata,key = "Key",value = "Value",cyl:disp) # “融化”cyl:disp两列,扔掉了disp列
name mpg Key Value
1 Mazda RX4 21.0 cyl 6.0
2 Mazda RX4 Wag 21.0 cyl 6.0
..
11 Mazda RX4 21.0 disp 160.0
12 Mazda RX4 Wag 21.0 disp 160.0
...
> gather(tdata,key = "Key",value = "Value",cyl:disp, mpg) # 和第一步一样的
name Key Value
1 Mazda RX4 cyl 6.0
...
11 Mazda RX4 disp 160.0
...
21 Mazda RX4 mpg 21.0
...
> gather(tdata,key = "Key",value = "Value",mpg,cyl,-disp) # “融化”mpg,cyl两列,不管disp这一列,但是不扔掉,和上面的有所区别
name disp Key Value
1 Mazda RX4 160.0 mpg 21.0
2 Mazda RX4 Wag 160.0 mpg 21.0
...
11 Mazda RX4 160.0 cyl 6.0
12 Mazda RX4 Wag 160.0 cyl 6.0
...
> gdata <- gather(tdata,key = "Key",value = "Value",cyl,disp,mpg) # 三列完全“融化”
> spread(gdata,key = "Key",value = "Value") # 合并,上一步的反向操作
name cyl disp mpg
1 Datsun 710 4 108.0 22.8
2 Duster 360 8 360.0 14.3
...
# 拆分或者合并某一列
> df <- data.frame(x = c(NA, "a.b", "a.d", "b.c"))
> df
x
1 <NA>
2 a.b
3 a.d
4 b.c
> separate(df,col=x,into = c("A","B")) # 拆分
A B
1 <NA> <NA>
2 a b
3 a d
4 b c
> separate(df,col=x,into = c("A","B"))
A B
1 <NA> <NA>
2 a b
3 a d
4 b c
> df <- data.frame(x = c(NA, "a.b-c", "a-d", "b-c"))
> separate(df,x,into = c("A","B"),sep = "-")
A B
1 <NA> <NA>
2 a.b c
3 a d
4 b c
> x <- separate(df,x,into = c("A","B"),sep = "-") # 合并
> unite(x,col ="AB",A,B,sep="-")
AB
1 NA-NA
2 a.b-c
3 a-d
4 b-c
dplyr()
> library(dplyr) # 载入包
> ls("package:dplyr") # 查看包内的方法
> dplyr::filter(iris,Sepal.Length>7.8) # 过滤出iris数据框中Sepal.Length>7.8的行数据
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 7.9 3.8 6.4 2 virginica
> dplyr::distinct(rbind(iris[1:5,],iris[1:3,])) # 去除重复行
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
> dplyr::slice(iris,11:15) # 对矩阵进行切片,选择任意行
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.4 3.7 1.5 0.2 setosa
2 4.8 3.4 1.6 0.2 setosa
3 4.8 3.0 1.4 0.1 setosa
4 4.3 3.0 1.1 0.1 setosa
5 5.8 4.0 1.2 0.2 setosa
> iris %>% head(15) %>% tail(5) # 等于这种效果,但是行索引不一样
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
11 5.4 3.7 1.5 0.2 setosa
12 4.8 3.4 1.6 0.2 setosa
13 4.8 3.0 1.4 0.1 setosa
14 4.3 3.0 1.1 0.1 setosa
15 5.8 4.0 1.2 0.2 setosa
> dplyr::sample_n(iris,2)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.4 1.5 0.2 setosa
2 6.7 3.1 4.4 1.4 versicolor
> dplyr::sample_n(iris,2) # 从一个矩阵里随机选出两列
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.9 3.0 5.1 1.8 virginica
2 6.3 2.5 4.9 1.5 versicolor
> dplyr::sample_frac(iris,0.01) # 从一个矩阵里随机选出1%的行
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.9 3.0 5.1 1.8 virginica
2 5.4 3.4 1.7 0.2 setosa
> dplyr::sample_frac(iris,0.01)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 6.6 3 4.4 1.4 versicolor
2 6.5 3 5.2 2.0 virginica
> head(dplyr::arrange(iris,Sepal.Length)) # 对数据框iris中的元素按照Sepal.Length进行排序
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 4.3 3.0 1.1 0.1 setosa
2 4.4 2.9 1.4 0.2 setosa
3 4.4 3.0 1.3 0.2 setosa
4 4.4 3.2 1.3 0.2 setosa
5 4.5 2.3 1.3 0.3 setosa
6 4.6 3.1 1.5 0.2 setosa
> iris %>% dplyr::arrange(Sepal.Length) %>% head() # 等于上一步
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 4.3 3.0 1.1 0.1 setosa
2 4.4 2.9 1.4 0.2 setosa
3 4.4 3.0 1.3 0.2 setosa
4 4.4 3.2 1.3 0.2 setosa
5 4.5 2.3 1.3 0.3 setosa
6 4.6 3.1 1.5 0.2 setosa
> dplyr::arrange(iris,desc(Sepal.Length)) %>% head() # 使用desc()函数进行逆序
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 7.9 3.8 6.4 2.0 virginica
2 7.7 3.8 6.7 2.2 virginica
3 7.7 2.6 6.9 2.3 virginica
4 7.7 2.8 6.7 2.0 virginica
5 7.7 3.0 6.1 2.3 virginica
6 7.6 3.0 6.6 2.1 virginica
> summarise(iris,avg=mean(Sepal.Length)) # 求Sepal.Length列的平均值,返回的是一个数据集对象
avg
1 5.843333
> mean(iris$Sepal.Length) # 返回的是一个数字
[1] 5.843333
> summarise(iris,sum=sum(Sepal.Length))
sum
1 876.5
> iris %>% dplyr::group_by(Species) %>% summarise(sum=sum(Sepal.Length)) # 将iris数据集按照Species列分类,然后计算每一类的Sepal.Length的和
# A tibble: 3 x 2
Species sum
<fct> <dbl>
1 setosa 250.
2 versicolor 297.
3 virginica 329.
> iris %>% group_by(Species) %>% summarise(avg=mean(Sepal.Width)) %>% arrange(avg) # 将iris数据集按照Species列分类,然后计算每一类的Sepal.Width的平均值,然后对其按照平均值排序(终于感受到R语言的牛逼之处了!!!)
# A tibble: 3 x 2
Species avg
<fct> <dbl>
1 versicolor 2.77
2 virginica 2.97
3 setosa 3.43
> iris %>% dplyr::mutate(new=Sepal.Length+Petal.Length) %>% head(3) # 对iris数据框新加一列(列名称为new,值为Length+Petal.Length)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species new
1 5.1 3.5 1.4 0.2 setosa 6.5
2 4.9 3.0 1.4 0.2 setosa 6.3
3 4.7 3.2 1.3 0.2 setosa 6.0
两个表的链接
> a=data.frame(x1=c("A","B","C"),x2=c(1,2,3)) # 创建两个数据框
> b=data.frame(x1=c("A","B","D"),x3=c(T,F,T))
> dplyr::left_join(a,b,by="x1") # 左连接
x1 x2 x3
1 A 1 TRUE
2 B 2 FALSE
3 C 3 NA
> dplyr::right_join(a,b,by="x1") # 右连接
x1 x2 x3
1 A 1 TRUE
2 B 2 FALSE
3 D NA TRUE
> dplyr::full_join(a,b,by="x1") # 全连接
x1 x2 x3
1 A 1 TRUE
2 B 2 FALSE
3 C 3 NA
4 D NA TRUE
> dplyr::semi_join(a,b,by="x1") # 求交集
x1 x2
1 A 1
2 B 2
> dplyr::semi_join(b,a,by="x1") # 求交集
x1 x3
1 A TRUE
2 B FALSE
> dplyr::anti_join(a,b,by="x1") # 求补集
x1 x2
1 C 3
> dplyr::anti_join(b,a,by="x1") # 求补集
x1 x3
1 D TRUE
> first <- mtcars %>% dplyr::mutate(Model = row.names(mtcars)) %>% slice(1:2)
> second <- mtcars %>% dplyr::mutate(Model = row.names(mtcars)) %>% slice(1:3)
> intersect(first, second) # 求交集
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21 6 160 110 3.9 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21 6 160 110 3.9 2.875 17.02 0 1 4 4
Model
Mazda RX4 Mazda RX4
Mazda RX4 Wag Mazda RX4 Wag
> union_all(first, second) # 求并集
mpg cyl disp hp drat wt qsec vs am gear
Mazda RX4...1 21.0 6 160 110 3.90 2.620 16.46 0 1 4
Mazda RX4 Wag...2 21.0 6 160 110 3.90 2.875 17.02 0 1 4
Mazda RX4...3 21.0 6 160 110 3.90 2.620 16.46 0 1 4
Mazda RX4 Wag...4 21.0 6 160 110 3.90 2.875 17.02 0 1 4
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4
carb Model
Mazda RX4...1 4 Mazda RX4
Mazda RX4 Wag...2 4 Mazda RX4 Wag
Mazda RX4...3 4 Mazda RX4
Mazda RX4 Wag...4 4 Mazda RX4 Wag
Datsun 710 1 Datsun 710
链式操作符% > %
,两个百分号中间夹着一个大于号 ,称为链式操作符,它功能是用于实现将一个函数的输出传递给下一个函数,作为下一个函数的输入。在RStudio
中可以使用ctrl+shift+M
快捷键输出出来。
R函数
参数选项
- 输入控制部分;
- 2、输出控制部分;
- 调节部分。
讲的是个啥东西呀~,实在是悟不透~
自定义函数
主要包括四部分:函数名称、函数声明、函数参数、函数体。
- 函数命令与功能相关;
- 可以是字母和数字的组合,但必须是字母开头。
一个小例子:设计一个求偏度与峰度的函数。
偏度(skewness)是统计数据分布偏斜方向和程度的度量,是统计数据分布非对称程度的数字特征。
峰度(peakedness; kurtosis)又称峰态系数。表征概率密度分布曲线在平均值处峰值高低的特征数。
mystats <- function(x,na.omit=FALSE) {
if(na.omit)
x <- x[!is.na(x)]
m <- mean(x)
n <- length(x)
s <- sd(x)
skew <- sum((x-m^3/s^3))/n
kurt <- sum((x-m^4/s^4))/n-3
return(c(n=n,mean=m,stdev=s,skew=skew,kurtosis=kurt))
}
R中的循环
if条件判断
> score=70;if (score >60 ) {print ("Passwd") } else {print ("Failed")}
[1] "Passwd"
> ifelse( score >60,print ("Passwd"),print ("Failed"))
[1] "Passwd"
[1] "Passwd"
while循环
> i <- 1; while (i <= 3) {
+ i = i+1
+ print("Hello, world.")
+ }
[1] "Hello, world."
[1] "Hello, world."
[1] "Hello, world."
for循环
> for (i in 1:3) {print("Hello, world.")}
[1] "Hello, world."
[1] "Hello, world."
[1] "Hello, world."
switch语句等
绘图函数
- 基础绘图系统;
- lattice包;
- ggplot2;
- grid。
绘图系统
- 高级绘图:高级绘图是一步到位,可以直接绘制出图;
- 低级绘图:而低级绘图,不能单独使用,必须在高级绘图产生图形的基础上,对图形进行调整,比如加一条线,加上标题文字等。
S3系统
属性
泛型函数
方法
报错记录
安装报错
> install.packages("VIM")
WARNING: Rtools is required to build R packages but is not currently installed. Please download and install the appropriate version of Rtools before proceeding:
当安装R包的时候显示这个,是提示需要安装Rtools
。官网链接:https://cran.r-project.org/bin/windows/Rtools/,需要按照自己的R版本来安装对应的Rtools。
安装过程一路回车即可,默认安装。安装完成之后,运行以下代码,不报错说明安装成功。
> writeLines('PATH="${RTOOLS40_HOME}\\usr\\bin;${PATH}"', con = "~/.Renviron")
继续安装包由发现新问题:
> install.packages("VIM")
将程序包安装入‘C:/Users/myxc/Documents/R/win-library/4.1’
(因为‘lib’没有被指定)
还安装相依关系‘DEoptimR’, ‘proxy’, ‘robustbase’, ‘vcd’, ‘e1071’, ‘laeken’, ‘ranger’, ‘data.table’
...
package ‘DEoptimR’ successfully unpacked and MD5 sums checked
Error in install.packages : ERROR: failed to lock directory ‘C:\Users\myxc\Documents\R\win-library\4.1’ for modifying
Try removing ‘C:\Users\myxc\Documents\R\win-library\4.1/00LOCK’
最后一句提示让删除某个文件夹试试,好家伙,试试就试试。
把上面的文件夹删除了,真就可以成功安装了。
已经可以成功载入安装的包了。
> library(VIM)
载入需要的程辑包:colorspace
载入需要的程辑包:grid
VIM is ready to use.
Suggestions and bug-reports can be submitted at: https://github.com/statistikat/VIM/issues
载入程辑包:‘VIM’
The following object is masked from ‘package:datasets’:
sleep