RVDSD的个人笔记本


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

R语言笔记之字符串-日期-格式化代码

发表于 2017-04-08 | 分类于 R
| 字数统计: 3,225 | 阅读时长 ≈ 14

字符串常用函数

is.character():判断是否是字符串;
nchar():有几个字符;
length():变量的长度
如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
> x <- "Hello, World!";x
[1] "Hello, World!"
> is.character(x)
[1] TRUE
> length(x)
[1] 1
> nchar(x)
[1] 13
> x2 <- c("Hello","World!")
> length(x2)
[1] 2
> nchar(x2)
[1] 5 6

内置数据集

R中有两个内置数据集,分别为LETTERS和letters,分别为大写字母和小写字母,如下所示:

1
2
3
4
5
6
7
8
9
10
> letters
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t"
[21] "u" "v" "w" "x" "y" "z"
> LETTERS
 [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T"
[21] "U" "V" "W" "X" "Y" "Z"
> letters[2:5]
[1] "b" "c" "d" "e"
> LETTERS[4:9]
[1] "D" "E" "F" "G" "H" "I"

字符串的连接和分离

字符串的分离strsplit()

strsplit()函数用于分离字符串,如下所示:

1
2
3
4
5
6
7
8
pangram <- "The quick brown fox jumps over the lazy dog"
pangram
length(pangram)
str(pangram)
pangram_split <- strsplit(pangram, " ")
pangram_split
length(pangram_split[[1]])
str(pangram_split)

运行结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
> pangram <- "The quick brown fox jumps over the lazy dog"
> pangram
[1] "The quick brown fox jumps over the lazy dog"
> length(pangram)
[1] 1
> str(pangram)
chr "The quick brown fox jumps over the lazy dog"
> pangram_split <- strsplit(pangram, " ")
> pangram_split
[[1]]
[1] "The" "quick" "brown" "fox" "jumps" "over" "the" "lazy" "dog"
> length(pangram_split[[1]])
[1] 9
> str(pangram_split)
List of 1
$ : chr [1:9] "The" "quick" "brown" "fox" ...

字符串的连接paste()

字符串的连接用的是paste函数,如下所示:

1
2
> paste(c("hello","world"))
[1] "hello" "world"

在为某些数据添加新的一列,进行分组时,很有用,如下所示:

1
2
3
> myvars<-paste("q",1:5,sep="") # 将q分别与1到5这五个数字连接起来
> myvars
[1] "q1" "q2" "q3" "q4" "q5"

字符串连接的注意事项

以字符串的分离结果为数据进行连接,结果如下所示:

1
2
> paste(result_split,collapse=" ")->x3;x3
[1] "c(\"The\", \"quick\", \"brown\", \"fox\", \"jumps\", \"over\", \"the\", \"lazy\", \"dog\")"

会发现字符之间出现的斜杠,原理如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
List of 1
 $ : chr [1:9] "The" "quick" "brown" "fox" ...
> result_split[[1]]
[1] "The"   "quick" "brown" "fox"   "jumps" "over"  "the"   "lazy"  "dog"  
> paste(result_split[[1]],collapse = " ")
[1] "The quick brown fox jumps over the lazy dog"
> str(result_split) 
List of 1
 $ : chr [1:9] "The" "quick" "brown" "fox" ...
> paste(result_split[[1]],collapse = " ")
[1] "The quick brown fox jumps over the lazy dog"
> paste(result_split[[1]],collapse = "*")
[1] "The*quick*brown*fox*jumps*over*the*lazy*dog"

因为分离后的字符串结果为列表(list),对列表直接用paste进行连接时,容易出现这种情况,因此要对列表的第1个元素进行连接才能避免这种情况。另外,在进行连接时主,要用于collapase参数,即用什么连接,案例中使用了空格与星号进行连接。

同时调用sep和collapse进行连接

以下面的这个例子中,先使用sep对不同向量进行连接,然后用collapse进行连接。

1
2
> paste(LETTERS[1:5],1:5,sep="_",collapse = "---")
[1] "A_1---B_2---C_3---D_4---E_5"

paste创建有规律的变量名

创造含有sample1-5的五个元素的向量:

1
2
> paste("Sample",1:5)
[1] "Sample 1" "Sample 2" "Sample 3" "Sample 4" "Sample 5"

字符的排序

排序用sort(),如果要倒序,则添加decreasing = TRUE,如下所示:

1
2
3
4
5
6
7
8
> sort(letters)
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t"
[21] "u" "v" "w" "x" "y" "z"
> sort(letters,decreasing = TRUE)
 [1] "z" "y" "x" "w" "v" "u" "t" "s" "r" "q" "p" "o" "n" "m" "l" "k" "j" "i" "h" "g"
[21] "f" "e" "d" "c" "b" "a"
> sort(result_split[[1]])
[1] "brown" "dog"   "fox"   "jumps" "lazy"  "over"  "quick" "the"   "The"

查找文本

所用的案例是美国州的名字,数据集为state.name,如果要获取字符串的子字符串,则有2种方法,分别为:

  1. 通过位置:例如让R返回从第5个位置开始的紧接的第3个字母。
  2. 通过模式,例如返回匹配某个模式的子集。

通过位置查询

此函数为substr,现在返回state.name中各个元素的第3到第6的子字符串,如下所示:

1
2
3
4
> head(state.name)
[1] "Alabama"    "Alaska"     "Arizona"    "Arkansas"   "California" "Colorado"  
> head(substr(state.name, start = 3,stop=6))
[1] "abam" "aska" "izon" "kans" "lifo" "lora"

通过模式查找匹配字符串

grep()函数可提取子字符串,它需要2个参数:

  1. pattern:想要查询的模式;
  2. x:被查询的向量。

需要注意的是grep()函数区分大小写
现在查找名称中含有“New”的州,如下所示:

1
2
3
4
> grep("New",state.name)
[1] 29 30 31 32
> grep("new",state.name)
integer(0)

返回的是数值变量,它表示的是元素的位置,例如:

1
2
3
4
> grep("New",state.name)
[1] 29 30 31 32
> state.name[c(29,30)]
[1] "New Hampshire" "New Jersey"

可以直接返回元素,如下所示:

1
2
> state.name[grep("New",state.name)]
[1] "New Hampshire" "New Jersey"    "New Mexico"    "New York"

文本替换

sub()函数可以用于检索文本中的特定模式,并将其替换为其它的文本;
gsub()可以实现所有的替换功能,它的三个参数为:查找的字符串,替换的字符串与被修改的文本。
例如替换A real world is cute中的cute与ugly:

1
2
3
x1 <- "A real world is cute."
x1
gsub("cute","ugly",x1)

子字符串的提取案例之一:

一个向量,包含3个文件名,分别为file_a.csv,file_b.csv,file_c.csv,现在要提取这3个文件名中的a、b和c,需要用两个步骤,分别为:

  1. 将字符串“file_”替换为空格;
  2. 将“.csv”去掉,如下所示:
1
2
3
4
5
> x <- c("file_a.csv","file_b.csv","file_c.csv")
> y <- gsub("file_","",x);y
[1] "a.csv" "b.csv" "c.csv"
> gsub(".csv","",y)
[1] "a" "b" "c"

大小写转换toupper()与tolower()

所用到的函数是toupper()与tolower(),如下所示:

1
2
3
4
5
6
7
8
9
> x <- c("word")
> toupper(x)
[1] "WORD"
> x <- c("word")
> y <- c("Excel")
> toupper(x)
[1] "WORD"
> tolower(y)
[1] "excel"

日期格式的创建

日期通常以字符串的形式输入到R中,然后转化为数值形式存储的日期变量,函数as.Date()用于执行这种转化,其语法为as.Date(x, "input_format"),其中x是
字符型数据,input_format则是读入日期的适当格式。

其格式如下所示:

1
2
3
4
5
6
7
8
%d 数字表示的日期(0~31) 例如01~31
%a 缩写的星期名 例如Mon
%A 非缩写的星期名 例如Monday
%m 月份(00~12) 例如00~12
%b 缩写的月份 例如Jan
%B 非缩写的月份 例如January
%y 两位数的年份 例如07
%Y 四位数的年份  例如2007

默认的日期格式为yyyy-mm-dd,语句为:

1
2
3
mydates <- as.Date(c("2007-06-22","2004-02-13"))
mydates
str(mydates)

结果如下:

mydates <- as.Date(c(“2007-06-22”,”2004-02-13”))
mydates
[1] “2007-06-22” “2004-02-13”
str(mydates)
Date[1:2], format: “2007-06-22” “2004-02-13”

weekdays()函数

返回某个日期是星期几如下所示:

1
2
3
4
5
6
7
8
9
## 格式转化
​```r
> strDates <- c("01/05/1965", "08/16/1975")
> dates <- as.Date(strDates, "%m/%d/%Y")
#输入的日期转化为对应日期,其中%m对应为月份,%d对应为日期,%Y对应为年
> dates
[1] "1965-01-05" "1975-08-16"
> str(dates)
 Date[1:2], format: "1965-01-05" "1975-08-16"

案例:

在leadership数据集中,日期是以mm/dd/yy的格式来表示的,现在将其转化为默认的yyyy-mm-dd格式,代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> myformat <- "%m/%d/%y"
> leadership$testDate <- as.Date(leadership$testDate, myformat)
> leadership
  managerID   testDate country gender age item1 item2 item3 item4 item5 stringsAsFactor
1         1 2008-10-24      US      M  32     5     4     5     5     5           FALSE
2         2 2008-10-28      US      F  45     3     5     2     5     5           FALSE
3         3 2008-10-01      UK      F  25     3     5     5     5     2           FALSE
4         4 2008-10-12      UK      M  39     3     3     4    NA    NA           FALSE
5         5 2009-05-01      UK      F  NA     2     2     1     2     1           FALSE
  agecat
1  Young
2  Young
3  Young
4  Young
5   <NA>

当前日期

1
2
3
4
5
6
7
8
9
> Sys.Date() # 给出当前日期
[1] "2014-01-18"
> date() #返回当前的日期和时间
[1] "Sat Jan 18 14:22:07 2014"
> today<-Sys.Date()
> format(today,format = "%B %d %Y") # 格式化当前日期
[1] "一月 18 2014"
> format(today,fomat ="%A")
[1] "2014-01-18"

两个日期的相减

1
2
3
4
> startdate <- as.Date("2004-02-12")
> enddate <- as.Date("2011-01-22")
> days <-enddate - startdate;days # 两个时间点之差
Time difference of 2536 days

用difftime()来计算时间间隔,并以星期,天,时,分,秒来表示。

1
2
3
4
> today <- Sys.Date()
> dob <- as.Date("1956-10-12")
> difftime(today, dob, units="weeks")
Time difference of 2988.143 weeks

as.character(dates)用于将日期转化为字符型变量,其它与日期有关的函数可以查看help(as.Date),help(strftime),与日期有关的包为lubridate,复杂日期计算有关
的包为fCalendar。

格式化R代码format()与sprintf()

这一步通常是在计算了所有的数据之后进行的,主要用于输出一份报表,使输出的数据看起来比较整齐 ,例如我们可以设置小数点对齐,或指定固定的列宽,或者是添加一些货币符号,或百分号。

如果要实现上述功能,用到的函数就是format(),它可以将数字变成美观的文本需要注意的是,此时数字会转换为文本,也就是转换为字符串,因此这一步要在最后一步进行。format()的参数如下所示:

  • trim:逻辑值。FALSE表示通过添加空格现实现文本的右对齐;TRUE会去掉前面的空格;
  • digits:控制显示的有效数字的个数;
  • nsmall:小数点后最少显示多少个数字;
  • decimal.mark:小数点的格式;
  • big.mark:设置小数点前整数部分的分段符;
  • small.mark:设置小数点后小数部分的分段符。

案例1:fromat()输出小数

看一个案例,我们要输出一个数字12345.6789,以逗号作为小数点,空格作为整数部分的分段符,点号作为小数部分的分段符(分段则是3个数字作为一段),如下所示:

1
2
format(12345.6789, diits = 9, decimal.mark=",",
big.mark = " ", small.mark = ".", small.interval = 3)

运行结果如下所示:

1
2
3
> format(12345.6789, diits = 9, decimal.mark=",",
+ big.mark = " ", small.mark = ".", small.interval = 3)
[1] "12 345,68"

使用print()函数时,也可以使用digits参数,如下所示:

1
2
> print(11/3,digits=3)
[1] 3.67

案例2:format()输出列表

计算mtcars中某几列的平均值,并且以两位小数的形式将其输出,如下所示:

1
2
x <- colMeans(mtcars[,1:4])
format(x, digits = 2, nsamll = 2)

运行结果如下所示:

1
2
3
4
> x <- colMeans(mtcars[,1:4])
> format(x, digits = 2, nsamll = 2)
mpg cyl disp hp
" 20.1" " 6.2" "230.7" "146.7"

案例3:sprintf()添加百分号%

sprintf是一种能够使用输出的字符以C语言的风格进行格式化,sprintf的第一个参数包含字符串或数字变量的点位符,其他参数则将逐个代入这些占位符1。

如下所示:

1
2
y <- seq(0.5, 0.55, 0.01)
sprintf("%.1f %%", 100*y)

运行结果如下所示:

1
2
> sprintf("%.1f %%", 100*y)
[1] "50.0 %" "51.0 %" "52.0 %" "53.0 %" "54.0 %" "55.0 %"

解释一下:"%.1f %%", 100*y是用来格式化字符串的,这在C与Python中很常见,这是告诉函数要将哪此部分远的为变量,%.1f表示将传入的第一个值进行格式化,要求显示小数点后一位数字 ,%%则是表示输出一个%。

案例4:sprintf()输出货币格式

输出货币格式只需要在sprintf()函数中添加上一个$符号即可,如下所示:

1
2
3
set.seed(1000)
z <- 1000*runif(5)
sprintf("$ %3.2f", z)

运行结果如下所示:

1
2
3
4
> set.seed(1000)
> z <- 1000*runif(5)
> sprintf("$ %3.2f", z)
[1] "$ 327.88" "$ 758.85" "$ 113.94" "$ 690.76" "$ 516.40"

案例5:sprintf()替换变量

再看一个sprintf()函数的案例,这个在Python或C中会经常遇到:

1
2
3
stuff <- c("bread", "cookies")
price <- c(2.1, 4)
sprintf("%s costed $ %3.2f", stuff, price)

运行结果如下所示:

1
2
3
4
> stuff <- c("bread", "cookies")
> price <- c(2.1, 4)
> sprintf("%s costed $ %3.2f", stuff, price)
[1] "bread costed $ 2.10" "cookies costed $ 4.00"

formatC()使用C语言风格格式化数字

formatC可以使用C语言风格来输出字符串,可以指定使用固定型或科学型的格式,小数的位数以及输出的宽度,无论使用哪种选项,输入都应该是numeric类型(包括数组),输出的是character字符向量或数组,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
> pow <- 1:3
> formatC(pow)
[1] "1" "2" "3"
> powers_of_e <- exp(pow)
> powers_of_e
[1] 2.718282 7.389056 20.085537
> formatC(powers_of_e)
[1] "2.718" "7.389" "20.09"
> formatC(powers_of_e,digits=3)
[1] "2.72" "7.39" "20.1"
> formatC(powers_of_e,digits=3,width = 10)
[1] " 2.72" " 7.39" " 20.1"

特殊字符

有一些特殊字符可以被以包含在字符中,例如我们可以通过\t来插入一个制表符,下面我们使用cat()函数来输出这种特殊字符,这里不使用print()是因为print执行的额外转换动作会所制表符\t转换成反斜框和一个t.。cat的参数fill = TRUE使光标在一行结束后移动到下一行,如下所示1:

1
2
> cat("foo\tbar", fill=TRUE)
foo bar

使用\n可以输出换行符,如下扬尘:

1
2
3
> cat("foo\nbar", fill = TRUE)
foo
bar

这里的转义字符与Python语言类似,不再多述。

文件路径

参考《数据的导入与导出》那篇笔记。

参考资料

  1. R语言轻松入门与提高 [法]Andrie de Vries ,[比利时]Joris Mey
1. 学习R.[美] Richard,Cotton 著刘军 译 ↩

R语言笔记之包的操作与内置数据集

发表于 2017-04-07 | 分类于 R
| 字数统计: 5,028 | 阅读时长 ≈ 20

R语言包的安装

在R中大概有几种包的安装方式。

install.packages()常规包的安装

括号里面包的名称要加英文引号,在列出的CRAN镜像站点列表中选择一个进行下载,例如

1
install.packages(“ggplot2”)

安装包的时候可以切换安装源,如下所示:

1
2
3
4
5
6
7
8
9
10
install.packages(pkgs, lib, repos = getOption("repos"),
contriburl = contrib.url(repos, type),
method, available = NULL, destdir = NULL,
dependencies = NA, type = getOption("pkgType"),
configure.args = getOption("configure.args"),
configure.vars = getOption("configure.vars"),
clean = FALSE, Ncpus = getOption("Ncpus", 1L),
verbose = getOption("verbose"),
libs_only = FALSE, INSTALL_opts, quiet = FALSE,
keep_outputs = FALSE, ...)

使用格式为:

1
install.packages("ABC",repos="http://mirror.bjtu.edu.cn/ ")

使用devtools从Github上安装包

如果是要从GitHub上安装包,需要先安装devtools,如下所示:

1
2
install.packages("devtools")
install_github("genomicsclass/dagdata")

其它的包安装命令,如下所示:

1
2
3
4
5
install.packages("installr") # 下载并安装 installr 包
library(installr) # 装载 installr 包
install.RStudio() # 下载并安装 RStudio IDE
install.Rtools() # 你需要 Rtools 来构建自己的包
install.git() #git 提供了代码的版本控制功能

如果要想把R包安装到其他位置,可以使用以下代码:

1
2
3
4
5
install.packages(
c("xts", "zoo"),
lib = "some/other/folder/to/install/to",
repos = "http://www.stats.bris.ac.uk/R/"
)

其中lib参数就是安装的包的位置,repos就是安装源。

通过BiocLite来安装生信工具

生信很多工具是在bioconductor上,因此需要biocLite,如下所示:

1
2
3
4
5
source("https://bioconductor.org/biocLite.R")
options(BioC_mirror="http://mirrors.ustc.edu.cn/bioc/")
# 使用相应的镜像
biocLite(c("ALL","CLL", "pasilla", "airway")) #数据包
biocLite(c("limma","DESeq2", "clusterProfiler")) #软件包

通过BiocManager来安装生信工具

在使用bioconductor时由于需要在线连接才能安装包,现在很多已经使用BiocManager的方式来安装,安装代码如下所示:

1
2
3
4
if (!requireNamespace("BiocManager", quietly = TRUE))
install.packages("BiocManager")
BiocManager::install("ballgown", version = "3.8")

批量下载并且加载R包

1
2
3
4
list.of.packages <- c("xx", "yy") # replace xx and yy with package names
new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(new.packages)
lapply(new.packages, require, character.only=T)

使用if语句安装并加载包

通过if语句,可以判断某个包是否存在,如果不存在,就先下载,后加载,如下所示:

1
2
3
4
5
#另外可以检测某个包是否存在,只有不存在时才会安装
if (! require ('reshape2')){
install.package("reshape2")
library(reshape2)
}

如果是bioconductor上的包,也可以按以下方式进行安装:

1
2
3
4
if (! require ('CLL')){
options(BioC_mirror="http://mirrors.ustc.edu.cn/bioc/")
BiocInstaller::biocLite('CLL',ask = F, suppressUpdates = T)
}

包的加载

包的载入函数为library()或require(),安装完包后,需要加载才能使用其中的函数,此时括号中不使用引号。两者的不同之处在于library()载入之后不返回任何信息,而require()载入后则会返回TRUE,因此require()适合用于程序的书写。

1
2
3
library(ggplot2)
require(foreign)
Loading required package: foreign

使用包中的函数,双冒号::

如果想不加载包就使用其中的函数,则需要使用双冒号,即::,看一个案例:

1
2
x <- rnorm(1000)
skewness(x)

运行结果如下所示:

1
2
> skewness(x)
Error in skewness(x) : could not find function "skewness"

结果显示,没有skewness这个函数,因为这个函数是moments包中的函数,没有加载这个包,就无法使用这个函数。现在我们在没有加载这个包的情况下,使用双冒号来看一下:

1
2
> moments::skewness(x)
[1] -0.01674

再用library()来使用一下:

1
2
3
> library(moments)
> skewness(x)
[1] -0.01674

使用双冒号这种方式在一种情况下比较适合。

这种情况就是:假设我们同时加载了A包与B包,A包中有一个名为a()的函数,B包中也有一个名为a()的函数。此时,如果先导入A包,再导入B包,B包中的a()函数就会屏蔽A包中的a()函数,也就是说,这两个同名函数就会出现冲突。

因此为了避免出现这种情况,可以不加载A包,也不加载B包,而是将它们的同名函数提取出来,如下所示:

1
2
fun1 <- A::a
fun2 <- B::a

如果你此时已经恰好载入一个包,想要解决绑定,就可以使用unloadNamespace()函数即可,例如:

1
unloadNamespace("moments")

查看一个包的帮助

1
help(package="base")

卸载包

detach(),这是library()的反向操作,此操作主要是为了避免某些包中的函数名称相同,造成冲突,注意与library()的参数不同,detach()参数为detach(package:包的名称),library(包的名称),例如:

1
2
3
4
5
6
7
8
library(ggplot2) #加载包
(.packages()) #列出当前已经加载的包
[1] "foreign" "ggplot2" "stats" "graphics" "grDevices" "utils"
[7] "datasets" "methods" "base"
detach(package:ggplot2) #卸载ggplot2包
(.packages()) #列出当前已经加载的包
[1] "foreign" "stats" "graphics" "grDevices" "utils" "datasets"
[7] "methods" "base"

删除包remove.packages()

使用条件:R语言自带的install.packages()函数来安装一个包时,都是默认安装最新版的。 但是有些R包的开发者他会引用其它的一些R包,但是它用的是旧版本的功能,自己来不及更新或者疏忽了。 而我们又不得不用他的包,这时候就不得不卸载最新版包,转而安装旧版本包。

查询加载的包search()

search()

1
2
3
4
search()
[1] ".GlobalEnv" "package:stats" "package:graphics"
[4] "package:grDevices" "package:utils" "package:datasets"
[7] "package:methods" "Autoloads" "package:base"

.libPaths()能够显示库所在的位置

1
2
3
.libPaths()
[1] "C:/Users/Cloud/Documents/R/win-library/3.1"
[2] "C:/Program Files/R/R-3.1.3/library"

library()显示库中有哪些包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
library()
backports Reimplementations of Functions Introduced Since
R-3.0.0
base64enc Tools for base64 encoding
bitops Bitwise Operations
bookdown Authoring Books and Technical Documents with R
Markdown
caTools Tools: moving window statistics, GIF, Base64,
ROC AUC, etc.
cellranger Translate Spreadsheet Cell Ranges to Rows and
Columns
digest Create Compact Hash Digests of R Objects
evaluate Parsing and Evaluation Tools that Provide More
Details than the Default
...
...

查看已经安装的包installed.packages()

函数installed.packages()

如下所示:

还可以这么输入代码:

1
2
pkgs <- installed.packages()
colnames(pkgs)

结果如下所示:

1
2
3
4
5
6
7
8
> pkgs <- installed.packages()
> colnames(pkgs)
[1] "Package" "LibPath" "Version"
[4] "Priority" "Depends" "Imports"
[7] "LinkingTo" "Suggests" "Enhances"
[10] "License" "License_is_FOSS" "License_restricts_use"
[13] "OS_type" "MD5sum" "NeedsCompilation"
[16] "Built"

当需要检查包是否已经安装时,可以使用以下代码:

1
c("moments", "Built") %in% installed.packages()[, "Package"]

结果如下所示:

1
2
> c("moments", "Built") %in% installed.packages()[, "Package"]
[1] TRUE FALSE

查看包的版本

查看包的版本可以通过下面代码实现:

1
2
> installed.packages()["ggplot2", "Version"]
[1] "3.2.0"

包的更新update.packages()

1
update.packages()

查看本地的包

查看默认加载的包,忽略基本的包

1
2
> getOption("defaultPackages")
[1] "datasets" "utils" "grDevices" "graphics" "stats" "methods"

查看当前已经加载过的包

1
2
3
> (.packages())
[1] "stats" "graphics" "grDevices" "utils" "datasets" "methods"
[7] "base"

显示所有可用的包

(.packages(all.available=TRUE))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(.packages(all.available=TRUE))
[1] "bitops" "car" "caTools" "coin"
[5] "colorspace" "crayon" "curl" "dichromat"
[9] "digest" "evaluate" "formatR" "fun"
[13] "ggplot2" "gtable" "highr" "htmltools"
[17] "httr" "ISwR" "jsonlite" "KMsurv"
[21] "knitr" "labeling" "lme4" "magrittr"
[25] "maps" "maptools" "markdown" "MatrixModels"
[29] "memoise" "mime" "minqa" "mnormt"
[33] "modeltools" "multcomp" "munsell" "mvtnorm"
[37] "nloptr" "openssl" "pbkrtest" "plyr"
[41] "praise" "psych" "quantreg" "R6"
[45] "RColorBrewer" "Rcpp" "RcppEigen" "RCurl"
[49] "reshape2" "rmarkdown" "sandwich" "scales"
[53] "sp" "SparseM" "stringi" "stringr"
[57] "swirl" "testthat" "TH.data" "yaml"
[61] "zoo" "base" "boot" "class"
[65] "cluster" "codetools" "compiler" "datasets"
[69] "foreign" "graphics" "grDevices" "grid"
[73] "KernSmooth" "lattice" "MASS" "Matrix"
[77] "methods" "mgcv" "nlme" "nnet"
[81] "parallel" "rpart" "spatial" "splines"
[85] "stats" "stats4" "survival" "tcltk"
[89] "tools" "utils"

自定义启动时候的加载包

如果需要长期使用某个包的话,每次开启都需要输入library(),比较麻烦,因此可以让R启动时自动加载某些包。在R的安装目录/etc/Rprofile.site加入下载语句:

例如让R启动时自动加载ggplot2包

1
2
local({old <- getOption(“defaultPackages”)
options(defaultPackages = c(old, “ggplot2”))})

安装包,并加载包

1
2
3
4
5
6
7
if(!require("multcomp")){
install.packages("multcomp")
library(multcomp)
}

常用R包的搜集

数据导入

以下R包主要用于数据导入和保存数据

  • feather:一种快速,轻量级的文件格式。在R和python上都可使用

  • readr:实现表格数据的快速导入。中文介绍可参考这里

  • readxl:读取Microsoft Excel电子表格数据

  • openxlsx:读取Microsoft Excel电子表格数据

  • googlesheets:读取google电子表格数据

  • haven:读取SAS,SPSS和Stata统计软件格式的数据

  • httr:从网站开放的API中读取数据

  • rvest:网页数据抓取包

  • xml2:读取HTML和XML格式数据

  • webreadr:读取常见的Web日志格式数据

  • DBI:数据库管理系统通用接口包

    • RMySQL:用于连接MySQL数据库的R包
    • RPostgres:用于连接PostgreSQL数据库的R包
    • bigrquery用于连接Google BigQuery的R包
  • PivotalR:用于读取Pivitol(Greenplum)和HAWQ数据库中的数据

  • dplyr:提供了一个访问常见数据库的接口

  • data.table:data.table包的fread()函数可以快速读取大数据集

  • git2r:用于访问git仓库

数据整理

以下R包主要用于数据整理,以便于你后续建模分析:

  • tidyr:用于整理表格数据的布局
  • dplyr:用于将多个数据表连接成一个整齐的数据集
  • purrr:函数式编程工具,在做数据整理时非常有用。
  • broom:用于将统计模型的结果整理成数据框形式
  • zoo:定义了一个名zoo的S3类型对象,用于描述规则的和不规则的有序的时间序列数据。

数据可视化

以下R包用于数据可视化:

  • ggplot2及其扩展:ggplot2包提供了一个强大的绘图系统,并实现了以下扩展

    • ggthemes:提供扩展的图形风格主题
    • ggmap:提供Google Maps,Open Street Maps等流行的在线地图服务模块
    • ggiraph:绘制交互式的ggplot图形
    • ggstance:实现常见图形的横向版本
    • GGally:绘制散点图矩阵
    • ggalt:添加额外的坐标轴,geoms等
    • ggforce:添加额外geoms等
    • ggrepel:用于避免图形标签重叠
    • ggraph:用于绘制网络状、树状等特定形状的图形
    • ggpmisc:光生物学相关扩展
    • geomnet:绘制网络状图形
    • ggExtra:绘制图形的边界直方图
    • gganimate:绘制动画图
    • plotROC:绘制交互式ROC曲线图
    • ggspectra:绘制光谱图
    • ggnetwork:网络状图形的geoms
    • ggradar:绘制雷达图
    • ggTimeSeries:时间序列数据可视化
    • ggtree:树图可视化
    • ggseas:季节调整工具
  • lattice:生成栅栏图

  • rgl:交互式3D绘图

  • ggvis:交互式图表多功能系统

  • htmlwidgets:一个专为R语言打造的可视化JS库

    • leaflet:绘制交互式地图
    • dygraphs:绘制交互式时间序列图
    • plotly:交互式绘图包,中文介绍详见这里
    • rbokeh:用于创建交互式图表和地图,中文介绍
    • Highcharter:绘制交互式Highcharts图
    • visNetwork:绘制交互式网状图
    • networkD3:绘制交互式网状图
    • d3heatmap:绘制交互式热力图,中文介绍
    • DT:用于创建交互式表格
    • threejs:绘制交互式3d图形和地球仪 -rglwidget:绘制交互式3d图形
    • DiagrammeR:绘制交互式图表
    • MetricsGraphics:绘制交互式MetricsGraphics图
  • rCharts:提供了对多个javascript数据可视化库(highcharts/nvd3/polychart)的R封装。

  • coefplot:可视化统计模型结果

  • quantmod:可视化金融图表

  • colorspace:基于HSL的调色板

  • viridis:Matplotlib viridis调色板

  • munsell:Munsell调色板

  • RColorBrewer:图形调色板

  • igraph:用于网络分析和可视化

  • latticeExtra:lattice绘图系统扩展包

  • sp:空间数据工具

数据转换

以下R包用于将数据转换为新的数据类型

  • dplyr:一个用于高效数据清理的R包。视频学习课程
  • magrittr:一个高效的管道操作工具包。
  • tibble:高效的显示表格数据的结构
  • stringr:一个字符串处理工具集
  • lubridate:用于处理日期时间数据
  • xts:xts是对时间序列数据(zoo)的一种扩展实现,提供了时间序列的操作接口。
  • data.table:用于快速处理大数据集
  • vtreat:一个对预测模型进行变量预处理的工具
  • stringi:一个快速字符串处理工具
  • Matrix:著名的稀疏矩阵包

统计建模与推断

下述R包是统计建模最常用的几个R包,其中的一些R包适用于多个主题。

  • car:提供了大量的增强版的拟合和评价回归模型的函数。
  • Hmisc:提供各种用于数据分析的函数
  • multcomp:参数模型中的常见线性假设的同时检验和置信区间计算,包括线性、广义线性、线性混合效应和生存模型。
  • pbkrtest用于线性混合效应模型的参数Bootstrap检验
  • MatrixModels:用于稠密矩阵和稀疏矩阵建模
  • mvtnorm:用于计算多元正态分布和t分布的概率,分位数,随机偏差等
  • SparseM:用于稀疏矩阵的基本线性代数运算
  • lme4:利用C++矩阵库 Eigen进行线性混合效应模型的计算。
  • broom:将统计模型结果整理成数据框形式
  • caret:一个用于解决分类和回归问题的数据训练综合工具包
  • glmnet:通过极大惩罚似然来拟合广义线性模型
  • gbm:用于实现随机梯度提升算法
  • xgboost:全称是eXtreme Gradient Boosting。是Gradient Boosting Machine的一个c++实现。目前已制作了xgboost工具的R语言接口。详见统计之都的一篇介绍
  • randomForest:提供了用随机森林做回归和分类的函数
  • ranger:用于随机森林算法的快速实现
  • h2o:H2O是0xdata的旗舰产品,是一款核心数据分析平台。它的一部分是由R语言编写的,另一部分是由Java和Python语言编写的。用户可以部署H2O的R程序安装包,之后就可以在R语言环境下运行了。
  • ROCR:通过绘图来可视化分类器的综合性能。
  • pROC:用于可视化,平滑和对比ROC曲线

沟通交流

以下R包用于实现数据科学结果的自动化报告,以便于你跟人们进行沟通交流。

  • rmarkdown :用于创建可重复性报告和动态文档
  • knitr:用于在PDF和HTML文档中嵌入R代码块
  • flexdashboard:基于rmarkdown,可以轻松的创建仪表盘
  • bookdown:以R Markdown为基础,用于创作书籍和长篇文档
  • rticles:提供了一套R Markdown模板
  • tufte:用于实现Tufte讲义风格的R Markdown模板
  • DT:用于创建交互式的数据表
  • pixiedust:用于自定义数据表的输出
  • xtable:用于自定义数据表的输出
  • highr:用于实现R代码的LaTeX或HTML格式输出
  • formatR:通过tidy_source函数格式化R代码的输出
  • yaml:用于实现R数据与YAML格式数据之间的通信。

自动化分析

以下R包用于创建自动化分析结果的数据科学产品:

  • shiny:一个使用R语言开发交互式web应用程序的工具。中文教程

    • shinydashboard:用于创建交互式仪表盘
    • shinythemes:给出了Shiny应用程序的常用风格主题
    • shinyAce:为Shiny应用程序开发者提供Ace代码编辑器。
    • shinyjs:用于在Shiny应用程序中执行常见的JavaScript操作
    • miniUI:提供了一个UI小部件,用于在R命令行中集成交互式应用程序
    • shinyapps.io:为创建的Shiny应用程序提供托管服务
    • Shiny Server Open Source:为Shiny应用程序提供开源免费的服务器
    • Shiny Server Pro:为企业级用户提供一个Shiny应用程序服务器
  • rsconnect:用于将Shiny应用程序部署到shinyapps.io

  • plumber:用于将R代码转化为一个web API

  • rmarkdown:用于创建可重复性报告和动态文档

  • rstudioapi:用于安全地访问RStudio IDE的API

程序开发

以下这些包主要用于开发自定义的R包:

  • RStudio Desktop IDE:R的IDE。大家都懂,不用解释。
  • RStudio Server Open Source:开源免费的RStudio服务器
  • RStudio Server Professional:商业版RStudio服务器
  • devtools:一个让开发R包变得简单的工具集
  • packrat:创建项目的特定库,用于处理包的版本问题,增强代码重现能力。
  • drat:一个用于创建和使用备选R包库的工具
  • testthat:单元测试,让R包稳定、健壮,减少升级的痛苦。
  • roxygen2:通过注释的方式,生成文档,远离Latex的烦恼。
  • purrr:一个用于 提供函数式编程方法的工具
  • profvis:用于可视化R代码的性能分析数据
  • Rcpp:用于实现R与C++的无缝整合。详见统计之都文章
  • R6:R6是R语言的一个面向对象的R包,可以更加高效的构建面向对象系统。
  • htmltools:用于生成HTML格式输出
  • nloptr:提供了一个NLopt非线性优化库的接口
  • minqa:一个二次近似的优化算法包
  • rngtools:一个用于处理随机数生成器的实用工具
  • NMF:提供了一个执行非负矩阵分解的算法和框架
  • crayon:用于在输出终端添加颜色
  • RJSONIO:rjson是一个R语言与json进行转的包,是一个非常简单的包,支持用 C类库转型和R语言本身转型两种方式。
  • jsonlite:用于实现R语言与json数据格式之间的转化
  • RcppArmadillo:提供了一个Armadillo C++ Library(一种C++的线性代数库)的接口

实验数据

以下R包给出了案例实战过程中可用的训练数据集:

  • babynames:包含由美国社会保障局提供的三个数据集
  • neiss:2009-2014年期间提供给美国急诊室的所有事故报告样本数据
  • yrbss:美国疾病控制中心2009-2013年期间青年危险行为监测系统数据
  • hflights:
  • USAboundaries:2011年全年休斯顿机场的所有航班数据
  • rworldmap:国家边界数据
  • usdanutrients:美国农业部营养数据库
  • fueleconomy:美国环保署1984-2015年期间的燃油经济数据
  • nasaweather:包含了一个覆盖中美洲的非常粗糙的24*24格地理位置和大气测量数据。
  • mexico-mortality:墨西哥死亡人数数据
  • data-movies和ggplotmovies:来自互联网电影数据库imdb.com的数据
  • pop-flows:2008年全美人口流动数据
  • data-housing-crisis:经过清洗后的2008美国房地产危机数据
  • gun-sales:纽约时报提供的有关枪支购买的每月背景调查统计分析数据
  • stationaRy:从成千上万个全球站点收集到的每小时气象数据
  • gapminder:摘自Gapminder的数据
  • janeaustenr:简·奥斯丁小说全集数据

查看R的版本

1
sessionInfo() # 要加括号

如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
> sessionInfo() # 要加括号
R version 3.4.0 (2017-04-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)
Matrix products: default
locale:
[1] LC_COLLATE=Chinese (Simplified)_China.936 LC_CTYPE=Chinese (Simplified)_China.936
[3] LC_MONETARY=Chinese (Simplified)_China.936 LC_NUMERIC=C
[5] LC_TIME=Chinese (Simplified)_China.936
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] downloader_0.4 rafalib_1.0.0
loaded via a namespace (and not attached):
[1] compiler_3.4.0 tools_3.4.0 RColorBrewer_1.1-2 digest_0.6.15

查看R语言的内置数据集data()

R的基本包中有一个叫datasets,里面全是示例数据集,供用户练习用。同时也可以使用data()来查看所有已经成功加载的包的数据集:

1
2
3
4
5
6
7
Data sets in package ‘datasets’:
AirPassengers Monthly Airline Passenger Numbers 1949-1960
BJsales Sales Data with Leading Indicator
BJsales.lead (BJsales) Sales Data with Leading Indicator
...
略

如果需要查看更完整的列表,包括已安装的所有包的数据,可以使用下面代码:

1
data(package = .packages(TRUE))

加载特定包中的数据集

如果想要访问任意数据集里面的数据,可以使用data()函数,传入数据集的名称以及所在的包名(如果这个包已经被加载了,就可以不用packages="包名"这个以参数了),如下所示:

1
2
data("kidney", package = "survival")
head(kidney)

这个命令是调用survival这个包中的kidney这个数据集,如下所示:

1
2
3
4
5
6
7
8
9
> data("kidney", package = "survival")
> head(kidney)
id time status age sex disease frail
1 1 8 1 28 1 Other 2.3
2 1 16 1 28 1 Other 2.3
3 2 23 1 48 2 GN 1.9
4 2 13 0 48 2 GN 1.9
5 3 22 1 32 1 Other 1.2
6 3 28 1 32 1 Other 1.2

参考资料

  1. http://www.xueqing.tv/cms/article/198
  2. http://blog.fens.me/
  3. 学习R.[美] Richard,Cotton 著刘军 译
  4. R 从安装开始:BiocLite 到 BiocManager
  5. R语言编程指南.任坤 著,王婷,赵孟韬,王泽贤 译

R语言笔记之文档检索与环境配置

发表于 2017-04-06 | 分类于 R
| 字数统计: 4,013 | 阅读时长 ≈ 16

R帮助函数

help.start() ,打开帮助文档首页

help.search("foo")或??foo,以foo为关键词搜索本地帮助文档,?Startup查看与R有关的启动文件信息;

example("foo") ,函数foo的使用示例(引号可以省略)

RSiteSearch("foo"),以 foo 为关键词,查询整个 http://search.r-project.org 网站的包,例如RSiteSearch("{Bayesian regression}")

apropos("foo",mode="function"), 列出名称中含有 foo 的所有可用函数 。apropos支持正则表达式,例如apropos("z$")表示列出所有以z为结尾的变量。而apropos("[4-9]")则是含有4到9之间数字的所有变量。

data(),列出当前已加载包中所含的所有可用示例数据集

vignette() ,列出当前已安装包中所有可用的 vignette 文档,vignette指是一类小文章,会描述某个R函数的用法。

vignette("foo"),为主题 foo 显示指定的 vignette 文档

demo(),演示某些R案例

browseVignettes(),查看当前系统里的Vignettes

注:在搜索帮助文档的过程中,可能会遇到R软件无法给出任何搜索项的相关信息的情况,如下所示:

1
2
3
help(adf.test)
## No documentation for 'adf.test' in specified packages and libraries:
## you could try '??adf.test'

若你确定该函数安装在计算机中,则导致这样情况的原因可能是由于包含该函数的R包未载入,你不清楚哪个R包中包含这个函数。要解决这样的问题,需要在所有已安装的R包中搜索该函数。使用错误消息中提示的方法来进行搜索(即用help.search命令),例如:

1
2
3
help.search("adf.test")
## starting httpd help server ...
## done

vignette()

有些软件包中也会包含vignette,这是一些附加的文档,例如简介、教程或者开发文档等。这些vignette都会在安装软件包时,作为软件包的一部分安装到计算机中。vignette显示在软件包的帮助页面底部。可以通过vignette命令查看计算机中包含的所有软件包的附加文档列表,也可以通过在vignette命令中指定某一软件包的名称,查看特定软件包所附带的vignette?,如下所示:

1
vignette(package="ggplot2")

每个vignette都对应一特定的名称,因此可以通过以下命令进行查看:vignette(“vignettename”) 。

某看某个函数的文档

用法:help(函数名)或?函数名

1
help(mean)

或者使用args函数快速获取函数的参数。例如,args(functionname)

或者用example函数查看函数的使用示例。例如example(functionname)

查看某个包的文档

用法:help(package=”包的名称”)

需要与这区别的是,查看一个函数的帮助命令是help(函数名),如果要查看一个包的帮助,操作与函数有所不同,需要加上package=,如下所示:

1
2
help(mean) # 查看函数mean的帮助文档
help(package="ggplot2") # 查看包ggplot2的帮助文档

网络资源

Rseek.org

http://rseek.org

Q&A网站

http://stackoverflow.com

针对编程有关问题的Q&A网站,例如数据结构、代码以及图表绘制等。

有关统计的的Q&A网站

http://stats.stackexchange.com

R官网

http://cran.r-project.org/web/views

网站中的任务视图,寻找并阅读与你研究相关的内容,其中能找到链接和相关软件包的简介。

关键词检索软件包

通过关键字检索合适的软件包

http://crantastic.org

sos

提供查询R包的其他方式:

http://cran.r-project.org/web/packages/sos/vignettes/sos.pdf

环境配置

历史命令保留

默认情况下,R会将一次对话中所有的命令都记录下来,方便随时重用,如果要将历史记录保存下来,可以使用savehistory()这个函数。默认情况下,R会当历史记录保存在当前工作目录下一个名为.Rhistory的文件中。

如果要将历史记录保存在其他文件,可以使用file参数,即savehistory(file="TestHistory"),扩展名对此文件并无影响。

如果要再次载入这个历史记录,使用可以loadhistory()命令,即loadhistory("TestHistory")。

查看R当前的版本

使用R.version()命令可以返回当前运行R的版本信息,包括运行平台本身的信息,比较丰富,如下所示:

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
31
32
33
34
35
36
37
38
39
40
41
42
> R.Version()
$platform
[1] "x86_64-w64-mingw32"
$arch
[1] "x86_64"
$os
[1] "mingw32"
$system
[1] "x86_64, mingw32"
$status
[1] ""
$major
[1] "3"
$minor
[1] "5.2"
$year
[1] "2018"
$month
[1] "12"
$day
[1] "20"
$`svn rev`
[1] "75870"
$language
[1] "R"
$version.string
[1] "R version 3.5.2 (2018-12-20)"
$nickname
[1] "Eggshell Igloo"

如果只是想知道R的版本号,则用getRversion()函数,如下所示:

1
2
> getRversion()
[1] ‘3.5.2’

设置R语言默认CRAN镜像

R使用的CRAN镜像信息保存在一个.RProfile为扩展名的文件中,这个文件位于用户的home文件夹或R的启动目录中,如果要想更改CRAN镜像就需要修改这个文件。

查看R语言可选的镜像要用到chooseCRANmirror()命名,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
> chooseCRANmirror()
Secure CRAN mirrors
1: 0-Cloud [https] 2: Algeria [https]
3: Australia (Canberra) [https] 4: Australia (Melbourne 1) [https]
5: Australia (Melbourne 2) [https] 6: Australia (Perth) [https]
7: Austria [https] 8: Belgium (Ghent) [https]
9: Brazil (PR) [https] 10: Brazil (RJ) [https]
... ...
... ...
Selection:

选择19(上海的镜像)。

输入options("repos")[[1]][1]就可以查看选择后的镜像,如下所示:

1
2
3
> options("repos")[[1]][1]
CRAN
"https://mirrors.tongji.edu.cn/CRAN"

将上面的镜像添加到.RProfile文件中即可 ,如下所示:

1
options(repos="https://mirrors.tongji.edu.cn/CRAN")

R代码的运行source()

运行R代码的方式有以下几种:

第一,若要在控制台上执行编辑器中的某一行代码,点击想要运行的那行代码,在RStudio中,按下Ctrl+Enter或按Run即可。

第二,若要运行编辑窗口中的所有代码,那么就需要点击源代码编辑器中的任何位置,按下Ctrl+Shift+Enter即可,或者是按Source按钮。或者是在控制台中直接输入source("R代码的路径+R代码文件")即可,例如在D盘下保存了一个R代码文件test.r,那么就需要输入source("D:/test.r"),按回车。

需要注意的是:Rstudio的编辑窗口中有一个Source on Save复选框,这个是表示自动保存,最好选上。

Worksapce

在一次R任务中,会导入数据,会创建变量,这些所有的内容称为Worksapce,它具体指的是,在所有会话中创建的变量,函数,载入的包。如果要查看当前Worksapce中创建的哪些变量,可以使用ls()命令。

保存Workspace命令save.image()

如果想要保存整个Worksapce,要用到save.image()命令,如下所示:

1
2
3
4
setwd("D:/")
test1 <- c(1:4)
test2 <- rep(1:3, 4)
save.image(file="test.Rdata")

现在就在D盘下保存了一个名为test.Rdata的文件,现在关闭Rstudio。去D盘下,再打开test文件,发现原来的变量test1和test2都还在,跟原来的一样。

Rda文件

Rda的全称是rdata,保存的是变量名与相应的多个变量,看以下代码:

1
2
3
4
setwd("D:/")
x <- c(1,2,3)
y <- c(4,5,6)
save(x,file="x.rda")

现在就在D盘保存了一个x.rda文件。当要载入这个文件时,要使用load()命令,如下所示:

1
2
3
rm(list=ls())
load("D:/x.rda")
x

save()与save.image()函数使用

在R中如果要保存某个变量或工作环境需要用到save()和save.iamge()命令,它们的用法如下所示:

1
2
3
4
5
6
7
8
9
Usage
save(..., list = character(),
file = stop("'file' must be specified"),
ascii = FALSE, version = NULL, envir = parent.frame(),
compress = isTRUE(!ascii), compression_level,
eval.promises = TRUE, precheck = TRUE)
save.image(file = ".RData", version = NULL, ascii = FALSE,
compress = !ascii, safe = TRUE)

其中参数含义如下所示:

  • list:一个包含要保存的对象名称的字符向量。
  • file:连接或保存数据的文件的名称。必须是保存的文件名。
  • ascii: ASCII码,默认FALSE。
  • envir: 寻找要保存的对象的环境。
  • compress:逻辑或字符串指定是否保存到指定文件是使用压缩。TRUE对应于gzip压缩,而字符串“gzip”、“bzip2”或“xz”指定压缩的类型。当文件是连接和工作空间格式版本时忽略。
  • save.image()只是“保存我当前工作空间”的捷径。

save()与save.image()函数的简单区别就在前者只保存一个变量(也可以保存多个),而后者可以一次保存所有的变量。

ls()查看当前对象

例如ls()可以查看当前环境中的所有对象,如下所示:

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
> a = 1:4
> b = c("a","b","C")
> ls()
[1] "a" "b"
> ls(pattern = "^is",baseenv()) # 列出base包中所有的以is开头的函数
# baseenv()表示返回base包中所有的环境
[1] "is.array" "is.atomic" "is.call"
[4] "is.character" "is.complex" "is.data.frame"
[7] "is.double" "is.element" "is.environment"
[10] "is.expression" "is.factor" "is.finite"
[13] "is.function" "is.infinite" "is.integer"
[16] "is.language" "is.list" "is.loaded"
[19] "is.logical" "is.matrix" "is.na"
[22] "is.na.data.frame" "is.na.numeric_version" "is.na.POSIXlt"
[25] "is.na<-" "is.na<-.default" "is.na<-.factor"
[28] "is.na<-.numeric_version" "is.name" "is.nan"
[31] "is.null" "is.numeric" "is.numeric.Date"
[34] "is.numeric.difftime" "is.numeric.POSIXt" "is.numeric_version"
[37] "is.object" "is.ordered" "is.package_version"
[40] "is.pairlist" "is.primitive" "is.qr"
[43] "is.R" "is.raw" "is.recursive"
[46] "is.single" "is.symbol" "is.table"
[49] "is.unsorted" "is.vector" "isatty"
[52] "isBaseNamespace" "isdebugged" "isFALSE"
[55] "isIncomplete" "isNamespace" "isNamespaceLoaded"
[58] "isOpen" "isRestart" "isS4"
[61] "isSeekable" "isSymmetric" "isSymmetric.matrix"
[64] "isTRUE"

ls.str()查看对象的类型

使用ls.str()命令可以查看变量的结构,如下所示:

1
2
3
> ls.str()
a : int [1:4] 1 2 3 4
b : chr [1:3] "a" "b" "C"

类似的函数还有browseEnv(),只是它是以HTML格式输出的,如下所示:

1
browseEnv()

工作空间管理

如果把R对象的运行方式比较为游戏规则,那么工作空间就可以看作游戏场地。如果要玩好游戏,你不仅需要熟悉 规则,也要熟悉场地,这里的规则就是指R语言的各种语法,这里的场地就是R语言的运行工作空间。

R语言的工作目录

当R开始运行时,它总是运行在某一个目录下的,这个目录就是R会话的工作目录,多数情况话,使用的就是绝对路径,例如C:\test这种工作,或者是使用相对路径,例如\test这样的。

在R中使用getwd()可以获取当前R的工作目录,使用setwd()是设置工作目录。

创建R项目

在Rstudio中要创建一个新项目就是使用File|New Project这个选项,具体的可以看Rstudio的实际操作。一旦创建了这个项目,就会在目录中创建一个扩展名为.Rproj文件,这个文件的核心内容其实就是几行代码。这个文件中储存了一些R的设置,一旦打开这个文件,这些设置就会启动,工作目录也将被设计为项目文件所在的位置,当我们进行一项数据分析任务时,最好就在Rstudio中创建一个.Rproj文件。

假设我们在Rstudio中创建了一个R项目,此时就会在设置的目录中创建了一个.Rproj文件,这个项目就包括R脚本,数据文件,文本文件,图表等。

检查工作环境

在R中,每个代码语句都是在指定环境中运行的,这个环境就是符号和其绑定物的集合,当我们当一个值赋给一个变量时,调用一个函数,或者对应一个函数名,R就会在当前的环境中寻找这个变量。如果在Rstudio的控制台中输入命令,它们会在全局环境中运行。例如当我们在Rstudio中开始一个新的R对话时,就是在一个空的全局环境中开始工作,这个空的全局环境就是没有定义任何变量的全局变量。

使用objects()这个命令就可以查看当前工作环境中的变量,如下所示:

1
2
3
4
5
6
x <- c(1, 2, 3)
y <- c("a", "b", "c")
z <- list(m = 1.5, n = c("x", "y", "z"))
objects()
ls()
ls.str()

运行结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
> x <- c(1, 2, 3)
> y <- c("a", "b", "c")
> z <- list(m = 1.5, n = c("x", "y", "z"))
> objects()
[1] "x" "y" "z"
> ls()
[1] "x" "y" "z"
> ls.str()
x : num [1:3] 1 2 3
y : chr [1:3] "a" "b" "c"
z : List of 2
$ m: num 1.5
$ n: chr [1:3] "x" "y" "z"

从上面结果可以看出来,这个工作空间中有三个变量,另外,使用ls()与objects()的目的是一样的,但是ls()用的更多。使用ls.str()可以查看所有的变量的数据类型,此时也可以查看特定类型的,例如ls.str(mode = "list")就可以列出列表类型的变量,此命令还支持正则表达式,使用ls.str(patten = "^\\w$", mode = "list")就列出匹配了所有字符串的list变量。

修改全局选项

R语言中能够查看所有选项的值,例如getOption()就可以查看,如下所示:

1
2
> getOption("digits")
[1] 7

在查看某个参数时,要加上引号,从上面就可以知道,R中默认的数值是7位,使用options()可以改变显示位数,如下所示:

1
2
3
4
5
6
7
8
> 123.4567891011121314145
[1] 123.4568
> options(digits = 2)
> 123.4567891011121314145
[1] 123
> options(digits = 4)
> 123.4567891011121314145
[1] 123.5

查看R程序运行时间

proc.time()查看用户时间

R中的proc.time()函数可以查看程序运行时,其实proc就是程序procedure的缩写,如下所示:

1
2
3
> proc.time()
用户 系统 流逝
0.32 0.73 26.81

由于系统是中文的,R中显示的是中文,其中用户(user)表示:R执行用户指标的CPU运行时间;系统(system)是指:系统所需要的时间,流逝(elapsed)是指R打开到现在总共运行的时间。

system.time()查看程序运行时间

使用system.time()函数可以查看R程序的运行时间,其语法是system.time(expr,gcFirst = TRUE)。

其中expr是需要运行的表达式,gcFirst是逻辑参数,system.time()这个函数实际上是调用了2次proc.time()函数,在程序运行前调用一次,在程序运行结束后又调用一次,然后计算这两次的时间差,如下所示:

1
2
3
4
system.time(for(i in 1:1000) mad(runif(1000)))
ptm <- proc.time() #将proc.time()的返回值保存到ptm对象里
for (i in 1:1000) mad(runif(1000))
proc.time() - ptm

运行结果如下所示:

1
2
3
4
5
6
7
8
> system.time(for(i in 1:1000) mad(runif(1000)))
用户 系统 流逝
0.17 0.00 0.17
> ptm <- proc.time() #将proc.time()的返回值保存到ptm对象里
> for (i in 1:1000) mad(runif(1000))
> proc.time() - ptm
用户 系统 流逝
0.15 0.00 0.16

再来看一个案例:

1
2
3
4
5
6
7
8
ptm <- proc.time()
x <- rnorm(100000)
y <- rnomr(100000)
z <- c()
for (i in 1:100000){
z <- c(z, x[i] + y[i])
}
proc.time() - ptm

运行结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
> ptm <- proc.time()
> x <- rnorm(100000)
> y <- rnomr(100000)
Error in rnomr(1e+05) : could not find function "rnomr"
> z <- c()
> for (i in 1:100000){
+ z <- c(z, x[i] + y[i])
+ }
> proc.time() - ptm
用户 系统 流逝
14.42 1.05 15.68

从上面结果我们可以发现,这段程序运行的时间为:15.68秒,这是因为在R中,使用for循环非常没有效率,最好不要用for循环。在上面的这个案例中,程序每次都增加一个元素z向量里,这样总共增加了100000次,如果我们已经知道了z的长度,首先给定z的长度,就可以提高运行效率,如下所示:

1
2
3
4
5
6
7
8
ptm <- proc.time()
x <- rnorm(100000)
y <- rnomr(100000)
z <- rep(NA, 100000)
for (i in 1:100000){
z[i] <- x[i] + y[i]
}
proc.time() - ptm

运行结果如下所示:

1
2
3
> proc.time() - ptm
用户 系统 流逝
0.19 0.00 0.19

用了0.19秒。

参考资料

  1. R语言-默认镜像设置
  2. R语言轻松入门与提高 [法]Andrie de Vries ,[比利时]Joris Mey
  3. R语言_save()函数用法
  4. 学习R[美]Richard,Cotton著,刘军译
  5. R语言编程指南.任坤 著,王婷,赵孟韬,王泽贤 译

R语言笔记之数据类型6-列表

发表于 2017-04-05 | 分类于 R
| 字数统计: 1,771 | 阅读时长 ≈ 8

列表

什么是列表

列表(list)为最复杂的数据类型,是一些对象或成分的有序集合,例如可以是向量,矩阵,数据框,或其他列表的组合。用list()创建:mylist<-list(object1,object2,...), 或命名列表:mylist<-list(name1=object1,name2=object2,...)。

列表(list)是一个广义的向量,它可以包含其它类型的对象,甚至可以包括其它列表。列表的灵活性非常有用,例如,当我们使用R拟合了一个线性模型时,其结果本质上就是一个列表,它里面包括了线性回归的详细结果,例如回归系数(数值向量),残差(数值向量)和QR分析(包含一个矩阵和其它对象的列表)等。

就我个人理解而言,列表更像是对数据框的拓展,它可以含有多个不同类型,不同长度的数据,而数据框只能是含有不同类型的相同数据。

创建列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
g<-"My First List"
h<-c(25,26,18,39)
j<-matrix(1:10,nrow=5)
k<-c("one","two","three")
mylist<-list(title=g,ages=h,j,k)
mylist #输出列表
## $title
## [1] "My First List"
##
## $ages
## [1] 25 26 18 39
##
## [[3]]
## [,1] [,2]
## [1,]1 6
## [2,]2 7
## [3,]3 8
## [4,]4 9
## [5,]5 10
##
## [[4]]
## [1] "one" "two" "three"

显示列表数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mylist[1]
## $title
## [1] "My First List"
mylist[2]
## $ages
## [1] 25 26 18 39
mylist[[2]]
## [1] 25 26 18 39
mylist["ages"]
## $ages
## [1] 25 26 18 39

删除列表数据

将需要删除的内容直接赋值为NULL即可,如下所示:

1
2
3
4
5
6
7
8
9
10
g<-"My First List"
h<-c(25,26,18,39)
j<-matrix(1:10,nrow=5)
k<-c("one","two","three")
mylist<-list(title=g,ages=h,j,k)
mylist #输出列表
mylist
mylist$ages
mylist$ages <- NULL
mylist

运行结果如下所示:

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
31
32
33
34
35
> mylist
$title
[1] "My First List"
$ages
[1] 25 26 18 39
[[3]]
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 3 8
[4,] 4 9
[5,] 5 10
[[4]]
[1] "one" "two" "three"
> mylist$ages
[1] 25 26 18 39
> mylist$ages <- NULL
> mylist
$title
[1] "My First List"
[[2]]
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 3 8
[4,] 4 9
[5,] 5 10
[[3]]
[1] "one" "two" "three"

提取列表子集

有的时候,我们需要从一个列表中提取多个元素,由这些元素组成的列表构成了原列表的一个子集。构建一个列表的子集,我们可以使用单层方括号,就像提取向量和矩阵中的元素一样。取些这些元素后,然后放到一个新列表中。
这里的方括号用法与其在向量中的用法非常类似。我们可以用字符向量表示成分名称,用数值向量表示成分位置,用逻辑向量指定选择标准,来取出列表元素。

例如mylist[[N]][M]表示提取N列中的第M个元素,如下所示:

1
2
3
4
5
6
7
g<-"My First List"
h<-c(25,26,18,39)
j<-matrix(1:10,nrow=5)
k<-c("one","two","three")
mylist<-list(title=g,ages=h,j,k)
mylist #输出列表
mylist[[2]][1] # 第取第2列第1个元素

结果运行如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
> mylist #输出列表
$title
[1] "My First List"
$ages
[1] 25 26 18 39
[[3]]
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 3 8
[4,] 4 9
[5,] 5 10
[[4]]
[1] "one" "two" "three"
> mylist[[2]][1] # 第取第2列第1个元素
[1] 25

判断列表完整

使用complete.cases()函数可以判断一个列表是否完整,但是,此函数要求列表的所有行长度都相等,如下所示:

1
2
3
4
h<-c(25,26,NA,NA)
k<-c("one","two","three","four")
mylist<-list(ages=h,k)
complete.cases(mylist)

运行结果如下所示:

1
2
> complete.cases(mylist)
[1] TRUE TRUE FALSE FALSE

更多情况下,complete.cases()函数用于判断数据框是否有缺失值,如下所示:

1
2
3
test <- data.frame(h<-c(25,26,NA,NA),
k<-c("one","two","three","four"))
complete.cases(test)

运行结果如下所示:

1
2
3
4
> test <- data.frame(h<-c(25,26,NA,NA),
+ k<-c("one","two","three","four"))
> complete.cases(test)
[1] TRUE TRUE FALSE FALSE

do.call()函数

do.call()函数可以根据名称或函数以及要传递给它的一个列表参数构建并执行一个函数的调用,它的用法如下所示:

1
do.call(what, args, quote = FALSE, envir = parent.frame())

参数说明如下所示:

  1. what:函数或者是一个要调用函数的名称的字符串;
  2. args:列表(list)参数,是函数执行的对象;
  3. quote:逻辑值,用于指定是否引用参数,默认情况下是FALSE,如果是FALSE,那么do.call()就会检测调用环境中的参数,而非envir中的参数。如果参数为TRUE,那么前面每个参数都会引用,
  4. envir:调用的函数。如果what参数是一个字符串,参数是一个符号或引号的表达式,envir这个参数比较有用。

看下面的案例:

第一个案例:

1
2
> do.call("complex", list(imag = 1:3))
[1] 0+1i 0+2i 0+3i

"complex"表示复数,这也是一个函数,list(imag=1:3)则是生成一个列表,并且将列表中的元素转换为复数。

第二个案例:如果我们已经有了一个数据框,可以通过c()函数添加另外的参数,如下所示:

1
2
3
4
tmp <- expand.grid(letters[1:2], 1:3, c("+", "-"))
tmp
do.call("paste", c(tmp, sep = ""))
do.call(paste, list(as.name("A"), as.name("B")), quote = TRUE)

运行结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> tmp <- expand.grid(letters[1:2], 1:3, c("+", "-"))
> tmp
Var1 Var2 Var3
1 a 1 +
2 b 1 +
3 a 2 +
4 b 2 +
5 a 3 +
6 b 3 +
7 a 1 -
8 b 1 -
9 a 2 -
10 b 2 -
11 a 3 -
12 b 3 -
> do.call("paste", c(tmp, sep = ""))
[1] "a1+" "b1+" "a2+" "b2+" "a3+" "b3+" "a1-" "b1-" "a2-" "b2-" "a3-" "b3-"
> do.call(paste, list(as.name("A"), as.name("B")), quote = TRUE)
[1] "A B"

在这个案例中,先创建了一个tmp数据框,然后调用了paste()函数,并且添加了""。

第三个案例:这里需要注意就是参数what加引号与不加引号的作用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
A <- 2
f <- function(x) print(x^2)
env <- new.env()
assign("A", 10, envir = env)
assign("f", f, envir = env)
f <- function(x) print(x)
f(A) # 2
do.call("f", list(A)) # 2
# 在env里,加引号和不加引号是有区别的
# 加引号,代表引用的是env里的
do.call("f", list(A), envir = env) # 4
do.call(f, list(A), envir = env) # 2
# 不加引号,代表是parent.frame()里的f
do.call("f", list(quote(A)), envir = env) # 100
do.call(f, list(quote(A)), envir = env) # 10
do.call("f", list(as.name("A")), envir = env) # 100
eval(call("f", A)) # 2
eval(call("f", quote(A))) # 2
eval(call("f", A), envir = env) # 4
eval(call("f", quote(A)), envir = env) # 100

结果如下所示:

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
31
32
33
34
> A <- 2
> f <- function(x) print(x^2)
> env <- new.env()
> assign("A", 10, envir = env)
> assign("f", f, envir = env)
> f <- function(x) print(x)
> f(A) # 2
[1] 2
> do.call("f", list(A)) # 2
[1] 2
> # 在env里,加引号和不加引号是有区别的
> # 加引号,代表引用的是env里的
>
> do.call("f", list(A), envir = env) # 4
[1] 4
> do.call(f, list(A), envir = env) # 2
[1] 2
> # 不加引号,代表是parent.frame()里的f
>
> do.call("f", list(quote(A)), envir = env) # 100
[1] 100
> do.call(f, list(quote(A)), envir = env) # 10
[1] 10
> do.call("f", list(as.name("A")), envir = env) # 100
[1] 100
>
> eval(call("f", A)) # 2
[1] 2
> eval(call("f", quote(A))) # 2
[1] 2
> eval(call("f", A), envir = env) # 4
[1] 4
> eval(call("f", quote(A)), envir = env) # 100
[1] 100

参考资料

  1. do.call 函数使用问题

R语言笔记之数据类型5-数组

发表于 2017-04-05 | 分类于 R
| 字数统计: 965 | 阅读时长 ≈ 5

数组

什么是数组

数组:一维数据是向量,二维数据是矩阵,数组是向量和矩阵的直接推广,是由三维或三维以上的数据构成的。

构建数组

数组函数是array(),语法是:array(dadta, dim),其中data必须是同一类型的数据,dim是各维的长度组成的向量。函数rowSums, colSums, rowMeans, colMeans分别可以计算行总和,行均值,列总和,列均值,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
a<-array(rep(1:3,each=3),dim=c(3,3))
a
## [,1] [,2] [,3]
## [1,]1 2 3
## [2,]1 2 3
## [3,]1 2 3
rowSums(a)
## [1] 6 6 6
colSums(a)
## [1] 3 6 9
table(a)
## a
## 1 2 3
## 3 3 3

多维数组

1
colSums (x, na.rm = FALSE, dims = 1) rowSums (x, na.rm = FALSE, dims = 1) colMeans(x, na.rm = FALSE, dims = 1) rowMeans(x, na.rm = FALSE, dims = 1)

其中dims为整数,表示哪个或哪些维数被看做行或列,对于row统计函数,dims+1及以后的维度被看做行,对于col函数,dims及以前的维度(1:dims)被看做列:

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
b <- array(rep(1:3, each=9), dim=c(3,3,3));b
## , , 1
##
## [,1] [,2] [,3]
## [1,]1 1 1
## [2,]1 1 1
## [3,]1 1 1
##
## , , 2
##
## [,1] [,2] [,3]
## [1,]2 2 2
## [2,]2 2 2
## [3,]2 2 2
##
## , , 3
##
## [,1] [,2] [,3]
## [1,]3 3 3
## [2,]3 3 3
## [3,]3 3 3
rowSums(b)
## [1] 18 18 18
rowSums(b,dims=1)
## [1] 18 18 18
rowSums(b,dims=2)
## [,1] [,2] [,3]
## [1,]6 6 6
## [2,]6 6 6
## [3,]6 6 6
colSums(b)
## [,1] [,2] [,3]
## [1,]3 6 9
## [2,]3 6 9
## [3,]3 6 9
colSums(b,dims=2)
## [1] 9 18 27
table(b)
## b
## 1 2 3
## 9 9 9

数组命名

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
x<-1:3 #建立向量x
names(x) #提取向量x的名称
## NULL
names(x)<-c("a","b","c");x#将a,b,c作为x的名称
## a b c
## 1 2 3
names(x)#显示向量x的名称
## [1] "a" "b" "c"
names(x)<-NULL;x #删除向量x的名称
## [1] 1 2 3
x<-matrix(1:4,2)
rownames(x)<-c("a","b") # 将行命名为a,b
colnames(x)<-c("c","d");x # 将列命名为c,d
## c d
## a 1 3
## b 2 4
dimnames(x)#返回包含两个向量的列表
## [[1]]
## [1] "a" "b"
##
## [[2]]
## [1] "c" "d"
a<-array(1:8,dim=c(2,2,2));a#建立数组a,维度为2,2,2
## , , 1
##
## [,1] [,2]
## [1,]1 3
## [2,]2 4
##
## , , 2
##
## [,1] [,2]
## [1,]5 7
## [2,]6 8
dimnames(a)<-list(c("a","b"),c("c","d"),c("e","f"));a # 将数组a的各组命名
## , , e
##
## c d
## a 1 3
## b 2 4
##
## , , f
##
## c d
## a 5 7
## b 6 8

行列求和,平均值和频数

简单数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
a <- array(rep(1:3, each=3), dim=c(3,3));a
## [,1] [,2] [,3]
## [1,]1 2 3
## [2,]1 2 3
## [3,]1 2 3
rowSums(a) # 求行的和
## [1] 6 6 6
colSums(a) # 求列的和 
## [1] 3 6 9
table(a) # 频数表
## a
## 1 2 3
## 3 3 3

多维数组

对于多维数组,rowSums, colSums, rowMeans, colMeans的使用稍为复杂点。它们的参数为:

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
b <- array(rep(1:3, each=9), dim=c(3,3,3));b
## , , 1
##
## [,1] [,2] [,3]
## [1,]1 1 1
## [2,]1 1 1
## [3,]1 1 1
##
## , , 2
##
## [,1] [,2] [,3]
## [1,]2 2 2
## [2,]2 2 2
## [3,]2 2 2
##
## , , 3
##
## [,1] [,2] [,3]
## [1,]3 3 3
## [2,]3 3 3
## [3,]3 3 3
rowSums(b)
## [1] 18 18 18
rowSums(b,dims=1)
## [1] 18 18 18
rowSums(b,dims=2)
## [,1] [,2] [,3]
## [1,]6 6 6
## [2,]6 6 6
## [3,]6 6 6
colSums(b)
## [,1] [,2] [,3]
## [1,]3 6 9
## [2,]3 6 9
## [3,]3 6 9
colSums(b,dims=2)
## [1] 9 18 27
table(b)
## b
## 1 2 3
## 9 9 9
c <- sample(letters[1:5], 10, replace=TRUE)
table(c)
## c
## a b d e
## 1 3 2 4

其实向量,矩阵和数组的性质和操作方式几乎完全相同。它们的共同特征就是这三种数据结构都属于同质数据类(homogeneous data types),即所侦破的一定是相同类型的元素。但是在R中,也存在着异质数据类(heterogeneous data types),即可以储存不同类型的元素,这能够极大地提高存储的灵活性,但同时也丧失了存储效率和运行效率。

参考资料

  1. R语言编程指南.任坤

R语言笔记之数据类型4-矩阵

发表于 2017-04-04 | 分类于 R
| 字数统计: 3,646 | 阅读时长 ≈ 18

矩阵

矩阵定义

矩阵是一个二维数组,只是每个元素都拥有相同的模式(数值型、字符型或逻辑型)。可通过函数matrix()创建矩阵。一般使用格式为:

1
2
3
myymatrix <- matrix(vector, nrow=number_of_rows, ncol=number_of_columns,
byrow=logical_value, dimnames=list(
char_vector_rownames, char_vector_colnames))

其中:

  • vector包含了矩阵的元素;
  • nrow和ncol用以指定行和列的维数;
  • dimnames包含了可选的、以字符型向量表示的行名和列名。
  • 选项 byrow 则表明矩阵应当按行填充( byrow=TRUE )还是按列填充( byrow=FALSE ),默认情况下按列填充。

创建矩阵

matrix()

此函数在默认情况下是按列进行填充,如下所示:

1
2
3
4
a <- 1:12
a
matrix(a, nrow=4, ncol=3) # 默认按列填充
matrix(a, nrow=3, ncol=3, byrow=T) # 按行填充

运行结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> a <- 1:12
> a
[1] 1 2 3 4 5 6 7 8 9 10 11 12
> matrix(a, nrow=4, ncol=3) # 默认按列填充
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
> matrix(a, nrow=3, ncol=3, byrow=T) # 按行填充
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9

dim()

通过dim来创建,先生成向量x,接着给向量x适当的维数,此例子中给向量的维数为5行,3列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> x <- 1:15
> x # 建立x
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
> x <- 1:15
> x # 建立x
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
> dim(x) #查看x的维度
NULL
> dim(x) <- c(5,3) # 将向量x转化为5行3列的矩阵
> x
[,1] [,2] [,3]
[1,] 1 6 11
[2,] 2 7 12
[3,] 3 8 13
[4,] 4 9 14
[5,] 5 10 15

矩阵命名

用法:Dimnames(Row_name,Col_name),给定行和列的名称,如果不需要给行或者列命名,则以NULL代替。例如:给下面的矩阵列命令:

1
2
3
4
5
6
7
a<-c(1,2,3,4,5,6);a
## [1] 1 2 3 4 5 6
a<-matrix(a,nrow=2,byrow=T,dimnames=list(c('a','b'),c('A','B','C')));a
## A B C
## a 1 2 3
## b 4 5 6

用rownames与colnames实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
b<-c(2,3,4,5,6,7) # 建立向量b
b
## [1] 2 3 4 5 6 7
b<-matrix(b,nrow=2) # 将向量b转化为矩阵
b
## [,1] [,2] [,3]
## [1,]2 4 6
## [2,]3 5 7
rownames(b)<-c("row_1","row_2") # 将矩阵行命名
colnames(b)<-c("col_1","col_2","col_3") # 将矩阵的列命名
b
## col_1 col_2 col_3
## row_12 4 6
## row_23 5 7

查看矩阵

查看矩阵的列/行相关信息

1
2
3
4
5
colnames(a) # 查看矩阵列名
## [1] "A" "B" "C"
rownames(a) # 查看矩阵行名
## [1] "a" "b"

查看矩阵的维度

1
2
3
4
5
6
7
8
dim(a) # 返回行与列数
## [1] 2 3
nrow(a) # 返回行数
## [1] 2
ncol(a) # 返回列数
## [1] 3

条件提取子矩阵

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
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
a # 查看矩阵a
## A B C
## a 1 2 3
## b 4 5 6
a[2,3] #取矩阵a的第2列,第3个元素
## [1] 6
a[,1] #取矩阵a的第1列
## a b
## 1 4
a[1,] # 取矩阵a的第1行
## A B C
## 1 2 3
c<-a[a[,2]>4] # 取矩阵a第2行并且大于4的元素,并将其赋值给c
c
## [1] 4 5 6
x<-c(1,2,3,4,5,6,7,8,8)
x<-matrix(x,nrow=3)
x
## [,1] [,2] [,3]
## [1,]1 4 7
## [2,]2 5 8
## [3,]3 6 8
x[,3] # 选取矩阵的第3列
## [1] 7 8 8
x[3,] # 选取矩阵的第3行
## [1] 3 6 8
y<-x[,3,drop=FALSE] # 选取x矩阵的第3列,并返回一个矩阵给y
y
## [,1]
## [1,] 7
## [2,] 8
## [3,] 8
x[,-1] # 不显示矩阵的第1列
## [,1] [,2]
## [1,]4 7
## [2,]5 8
## [3,]6 8
x[-1,] # 不显示矩阵的第1行
## [,1] [,2] [,3]
## [1,]2 5 8
## [2,]3 6 8
x[,-(1:2)] # 不显示矩阵的第1,2列
## [1] 7 8 8
z<-x[,-(1:2),drop=FALSE] #不显示矩阵x的第1,2列,并且返回为一矩阵y
z
## [,1]
## [1,] 7
## [2,] 8
## [3,] 8

提取矩阵的行或列

nrow与ncol函数: nrow与ncol函数返回行或列的某一个数字。NCOL与NROW用于向量,即把向量作为单行的矩阵处理。 用法: nrow(x) ncol(x) NCOL(x) NROW(x) 参数: x:向量,或数据框; 值:长度为1或无的整数: 类似的有dim函数,如下所示:

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
ma <- matrix(1:12, 3, 4);ma # 建矩阵3行4列的矩阵
## [,1] [,2] [,3] [,4]
## [1,]1 4 710
## [2,]2 5 811
## [3,]3 6 912
nrow(ma) # 行数为3
## [1] 3
ncol(ma) # 列数为4
## [1] 4
y <-array(1:24, dim = 2:4);y # 建2行4列的数组
## , , 1
##
## [,1] [,2] [,3]
## [1,]1 3 5
## [2,]2 4 6
##
## , , 2
##
## [,1] [,2] [,3]
## [1,]7 9 11
## [2,]8 10 12
##
## , , 3
##
## [,1] [,2] [,3]
## [1,]13 15 17
## [2,]14 16 18
##
## , , 4
##
## [,1] [,2] [,3]
## [1,]19 21 23
## [2,]20 22 24
ncol(y)
## [1] 3
NCOL(1:12) # NCOL把数组作为单行的矩阵处理
## [1] 1
NROW(1:12) # 12
## [1] 12

矩阵的运算

矩阵相乘%*%

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
a
## A B C
## a 1 2 3
## b 4 5 6
d <- c(1:6)
d <- matrix(d,nrow=3)
d
## [,1] [,2]
## [1,]1 4
## [2,]2 5
## [3,]3 6
e<-a%*%d
e
## [,1] [,2]
## a 14 32
## b 32 77

只有当矩阵a的列数与矩阵b的行数相等时a×b才有意义。一个m×n的矩阵a(m,n)左乘一个n×p的矩阵b(n,p),会得到一个m×p的矩阵c(m,p),满足矩阵乘法满足结合律,但不满足交换律。 运算的法则: 矩阵a的第1行的3个元素(1,2,3)分别与矩阵b第1列的3个元素(1,2,3)相乘,其和为结果为e[1,1],即e[1,1]=1×1+2×2+3×3=14; 矩阵a的第1行的3个元素(1,2,3)分别与矩阵b第2列的3个元素(4,5,6)相乘1×4+2×5+3×6=32,得到e[1,2]; 矩阵a的第2行的3个元素(4,5,6)分别与矩阵b第1列的3个元素(1,2,3)相乘4×1+5×2+6×3=32,得到e[2,1]; 矩阵a的第2行的3个元素(4,5,6)分别与矩阵b第2列的3个元素(4,5,6)相乘4×4+5×5+6×6=77,得到e[2,2].

矩阵合并

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
m1<-matrix(1,nrow=2,ncol=2)
m1 # 建立矩阵m1,2行2列,值为1
## [,1] [,2]
## [1,]1 1
## [2,]1 1
m2<-matrix(2,nrow=2,ncol=2)
m2 # 建立矩阵m2,2行2列,值为2
## [,1] [,2]
## [1,]2 2
## [2,]2 2
m_rbind<-rbind(m1,m2);m_rbind # 对两个矩阵m1,m2进行行合并,即上下合并
## [,1] [,2]
## [1,]1 1
## [2,]1 1
## [3,]2 2
## [4,]2 2
m_cbind<-cbind(m1,m2);m_cbind #对两个矩阵m1,m2进行列合并,即左右合并
## [,1] [,2] [,3] [,4]
## [1,]1 1 22
## [2,]1 1 22

星号表示相乘

把两个矩阵中每个对应的元素相乘,例子中a与b拥有相同的维度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
a
## A B C
## a 1 2 3
## b 4 5 6
b
## col_1 col_2 col_3
## row_12 4 6
## row_23 5 7
result<-a*b #将矩阵a与矩阵b相乘,并将其结果给result
result
## AB C
## a 2 8 18
## b 12 25 42

如果维度不同,如下所示:

1
2
3
4
5
6
7
8
9
10
a
## A B C
## a 1 2 3
## b 4 5 6
c
## [1] 4 5 6
a*c # a矩阵中的每一列与c的每一行相乘,循环c
## AB C
## a 4 12 15
## b 20 20 36

增加行与列

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
31
32
33
34
35
f<-matrix(,4,2) # 建立4行2列的空矩阵f
f
## [,1] [,2]
## [1,]NA NA
## [2,]NA NA
## [3,]NA NA
## [4,]NA NA
f[c(1,3),]<-matrix(c(1,2,3,4)) #取f的1行与3行,将向量(1,2,3,4)填充进去,默认按列填充
f
## [,1] [,2]
## [1,]1 3
## [2,]NA NA
## [3,]2 4
## [4,]NA NA
g<-matrix(,4,2)
g
## [,1] [,2]
## [1,]NA NA
## [2,]NA NA
## [3,]NA NA
## [4,]NA NA
g[c(1,3),]<-matrix(c(1,2,3,4),byrow=FALSE) # byrow=FALSE则按行填充
g
## [,1] [,2]
## [1,]1 3
## [2,]NA NA
## [3,]2 4
## [4,]NA NA

矩阵转置t()

1
2
3
4
5
6
7
8
9
10
11
12
13
f
## [,1] [,2]
## [1,]1 3
## [2,]NA NA
## [3,]2 4
## [4,]NA NA
h<-t(f)
h
## [,1] [,2] [,3] [,4]
## [1,]1 NA 2NA
## [2,]3 NA 4NA

取对角元素diag()

若要取一个方阵的对角元素,对一个向量应用diag()函数将产生以这个向量为对角元素的对角矩阵,对一个正整数k应用diag()函数将产生k维单位矩阵,如下所示:

1
2
3
4
5
6
7
8
9
10
j<-c(1,2,3,4,5,6,7,8,9)
j<-matrix(j,nrow=3)
j_diag<-diag(j) #取对角
j_diag
diag(diag(j_diag))
diag(3)
A <- matrix(1:16,nrow=4,ncol=4)
diag(A)
diag(3)

结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> j_diag
[1] 1 5 9
> diag(diag(j_diag))
[1] 1 5 9
> diag(3)
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 1 0
[3,] 0 0 1
> A <- matrix(1:16,nrow=4,ncol=4)
> diag(A)
[1] 1 6 11 16
> diag(3)
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 1 0
[3,] 0 0 1

求各行与列的总和与均值rowSum(),rowMeans()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
j
## [,1] [,2] [,3]
## [1,]1 4 7
## [2,]2 5 8
## [3,]3 6 9
rowSums(j) # 求各行的总和
## [1] 12 15 18
rowMeans(j) # 求行的均值
## [1] 4 5 6
colSums(j) #求各列的总和
## [1] 6 15 24
colMeans(j) #求各列的均值
## [1] 2 5 8

矩阵的特征值与特征向量eigen()

矩阵A的谱分解为A=UΛU,其中Λ是由A的特征值组成的对角矩阵,U的列为A的特征值对应的特征向量,在R中可以使用eigen()得到U和A,eigen(x,symmertic, only.values=FALSE,EISPACK=FALSE),其中参数symmetric项是逻辑值,是F或T,它用于指定矩阵x是否为对称矩阵,如果不指定,系统将自动检验x是否为对称矩阵,如下所示:

1
2
3
4
5
6
7
8
9
10
> eigen(j)
eigen() decomposition
$values
[1] 1.611684e+01 -1.116844e+00 -5.700691e-16
$vectors
[,1] [,2] [,3]
[1,] -0.4645473 -0.8829060 0.4082483
[2,] -0.5707955 -0.2395204 -0.8164966
[3,] -0.6770438 0.4038651 0.4082483

矩阵的求逆solve()

矩阵求逆可用函数solve(),应用sovle(A,b)运算结果可以解线性方程组Ax=b,若b缺少,则系统默认为单位矩阵,因此可以用其进行矩阵求逆,如下所示:

1
2
A <- matrix(rnorm(16),4,4);A
solve(A)

结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
> A <- matrix(rnorm(16),4,4);A
[,1] [,2] [,3] [,4]
[1,] 0.3981 1.4330 0.56972 0.6897
[2,] -0.6120 1.9804 -0.13505 0.0280
[3,] 0.3411 -0.3672 2.40162 -0.7433
[4,] -1.1294 -1.0441 -0.03924 0.1888
> solve(A)
[,1] [,2] [,3] [,4]
[1,] 0.12130 -0.4308 -0.063267 -0.6283
[2,] 0.04397 0.3764 0.007696 -0.1862
[3,] 0.30921 -0.0369 0.344768 0.2331
[4,] 1.03306 -0.5029 -0.264247 0.5569

矩阵的特征值与特征向量eigen()

矩阵A的谱分解为$A=U\Lambda U’$,其中$\Lambda$是由$A$的特征值组成的对角矩阵,$U$的列为$A$的特征值对应的特征向量,在R中可以使用eigen()得到$U$和$A$,此函数参数如下所示:

1
eigen(x,symmetric,only.values=FALSE, EISPACK=FALSE)

其中,x为矩阵,symmetric项指定矩阵x是否为对称矩阵,若不指定,系统将自动检测x是否为对称矩阵,如下所示:

1
2
3
4
A <- diag(4) +1
A.e <- eigen(A, symmetric=T)
A.e
A.e$vectors%*%diag(A.e$values)%*%t(A.e$vectors)

结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
> A <- diag(4) +1
> A.e <- eigen(A, symmetric=T)
> A.e
eigen() decomposition
$values
[1] 5 1 1 1
$vectors
[,1] [,2] [,3] [,4]
[1,] -0.5 0.8660 0.0000 0.0000
[2,] -0.5 -0.2887 -0.5774 -0.5774
[3,] -0.5 -0.2887 -0.2113 0.7887
[4,] -0.5 -0.2887 0.7887 -0.2113
> A.e$vectors%*%diag(A.e$values)%*%t(A.e$vectors)
[,1] [,2] [,3] [,4]
[1,] 2 1 1 1
[2,] 1 2 1 1
[3,] 1 1 2 1
[4,] 1 1 1 2

矩阵的Choleskey分解

对于正定矩阵A,可对其进行Choleskey分解,即$A=P’P$,其中$P$为上三角矩阵,在R中可以用函数chol()进行Choleskey分解,如下所示:

1
2
3
A <- diag(4) +1
A.c <-chol(A);A.c
t(A.c)%*%A.c

结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
> A <- diag(4) +1
> A.c <-chol(A);A.c
[,1] [,2] [,3] [,4]
[1,] 1.414 0.7071 0.7071 0.7071
[2,] 0.000 1.2247 0.4082 0.4082
[3,] 0.000 0.0000 1.1547 0.2887
[4,] 0.000 0.0000 0.0000 1.1180
> t(A.c)%*%A.c
[,1] [,2] [,3] [,4]
[1,] 2 1 1 1
[2,] 1 2 1 1
[3,] 1 1 2 1
[4,] 1 1 1 2

矩阵奇异值分解svd()

A为$m \times n$矩阵,$rank(A)=r$,可以分解为$A=UDV^T$,其中,$U’U=V’V=I$。在R中可以使用函数svd()进行奇异值分解,如下所示:

1
2
3
A <- matrix(1:18, 3,6);A
A.s <- svd(A);A.s
A.s$u%*%diag(A.s$d)%*%t(A.s$v)

结果如下所示:

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
> A <- matrix(1:18, 3,6);A
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 4 7 10 13 16
[2,] 2 5 8 11 14 17
[3,] 3 6 9 12 15 18
> A.s <- svd(A);A.s
$d
[1] 4.589e+01 1.641e+00 1.367e-15
$u
[,1] [,2] [,3]
[1,] -0.5290 0.7439 0.4082
[2,] -0.5761 0.0384 -0.8165
[3,] -0.6231 -0.6671 0.4082
$v
[,1] [,2] [,3]
[1,] -0.07736 -0.7196 -0.40767
[2,] -0.19033 -0.5089 0.57456
[3,] -0.30330 -0.2983 -0.02801
[4,] -0.41627 -0.0876 0.22266
[5,] -0.52924 0.1231 -0.62121
[6,] -0.64221 0.3337 0.25966
> A.s$u%*%diag(A.s$d)%*%t(A.s$v)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 4 7 10 13 16
[2,] 2 5 8 11 14 17
[3,] 3 6 9 12 15 18

矩阵QR分解qr()

A为$m \times n$矩阵时可以进行QR分解,$A=QR$,其中,$Q’Q=I$,在R中可以使用qr()进行QR分解,如下所示:

1
2
A <- matrix(1:16,4,4);A
qr(A)

结果如下所示:

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
> A <- matrix(1:16,4,4);A
[,1] [,2] [,3] [,4]
[1,] 1 5 9 13
[2,] 2 6 10 14
[3,] 3 7 11 15
[4,] 4 8 12 16
> qr(A)
$qr
[,1] [,2] [,3] [,4]
[1,] -5.4772 -12.7802 -2.008e+01 -2.739e+01
[2,] 0.3651 -3.2660 -6.532e+00 -9.798e+00
[3,] 0.5477 -0.3782 1.601e-15 2.217e-15
[4,] 0.7303 -0.9125 -5.547e-01 -1.478e-15
$rank
[1] 2
$qraux
[1] 1.183e+00 1.156e+00 1.832e+00 1.478e-15
$pivot
[1] 1 2 3 4
attr(,"class")
[1] "qr"

矩阵kronecker积kronecker()

A为$m \times n$矩阵,B为$h \times k$矩阵,而A与B的kronecker积为一个$nh \times mk$维矩阵,在R中,使用函数kronecker()来过计算kronecker积,如下所示:

1
2
3
A <- matrix(1:4,2,2);A
B <- matrix(rep(1,4),2,2);B
kronecker(A,B)

结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> A <- matrix(1:4,2,2);A
[,1] [,2]
[1,] 1 3
[2,] 2 4
> B <- matrix(rep(1,4),2,2);B
[,1] [,2]
[1,] 1 1
[2,] 1 1
> kronecker(A,B)
[,1] [,2] [,3] [,4]
[1,] 1 1 3 3
[2,] 1 1 3 3
[3,] 2 2 4 4
[4,] 2 2 4 4

行列式计算det()

在矩阵中,计算行列式的值可以使用函数det(),如下所示:

1
2
3
4
5
6
7
8
9
10
A <- matrix(1:16,4)
B <- A
C <- matrix(1:4,2)
B[row(A) < col(A)] =0 # 构建一个新矩阵
A
B
C
det(A)
det(B)
det(C)

计算结果如下所示:

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
> A <- matrix(1:16,4)
> B <- A
> C <- matrix(1:4,2)
> B[row(A) < col(A)] =0 # 构建一个新矩阵
> A
[,1] [,2] [,3] [,4]
[1,] 1 5 9 13
[2,] 2 6 10 14
[3,] 3 7 11 15
[4,] 4 8 12 16
> B
[,1] [,2] [,3] [,4]
[1,] 1 0 0 0
[2,] 2 6 0 0
[3,] 3 7 11 0
[4,] 4 8 12 16
> C
[,1] [,2]
[1,] 1 3
[2,] 2 4
> det(A)
[1] 0
> det(B)
[1] 1056
> det(C)
[1] -2

参考资料

  1. 多元统计分析及R语言建模(第4版) [Multivariate Statistical Analysis and Modeling for R Language] .王斌会 著
  2. R数据分析之方法与案例详解.方匡南,朱建平,姜叶飞.电子工业出版社

R语言笔记之数据类型3-数据框

发表于 2017-04-03 | 分类于 R
| 字数统计: 5,133 | 阅读时长 ≈ 27

数据框定义

一种矩阵形式的数据,但数据框中各列可以是不同类型的数据。数据框每列是一个变量,每行是一个观测。数据框可以看成是矩阵的推广,也可看作一种特殊的列表对象。

数据框的创建

data.frame()

通过data.frame函数来创建数据框,该函数包含的主要参数为: data.frame(…, row.names = NULL, check.rows = FALSE, check.names = TRUE, stringsAsFactors = default.stringsAsFactors()) 如下所示:

1
2
3
4
5
6
7
rats <- c(1:6)
group <- c("postive","postive","model","model","control","control")
sex <- c("F","M","F","M","F","M")
glu.d1 <- c(11.97,12.97,27.34,23.97,6.79,5.19)
glu.d7 <- c(12.97,13.97,25.56,23.97,5.79,6.19)
rat.data <- data.frame(rats,group,sex,glu.d1,glu.d7)
rat.data

rat.data
rats group sex glu.d1 glu.d7
1 1 postive F 11.97 12.97
2 2 postive M 12.97 13.97
3 3 model F 27.34 25.56
4 4 model M 23.97 23.97
5 5 control F 6.79 5.79
6 6 control M 5.19 6.19

注:在R中,当创建数据框的时候,它会将字符串类型的数据自动转换为因子型数据,此时需要添加stringsAsFactors = FALSE即可。

expand.grid()

通过expand.grid()创建一个数据框,此函数可以创建元素所有可能的组合:

1
2
x<-expand.grid(h=c(60,80),w=c(100,300),sex=c("M","F"))
x

x
h w sex
1 60 100 M
2 80 100 M
3 60 300 M
4 80 300 M
5 60 100 F
6 80 100 F
7 60 300 F
8 80 300 F

查看数据框信息

1
class(rat.data) # 查看类型

class(rat.data) # 查看类型
[1] “data.frame”

1
class(rat.data$sex) # 查看某列的类型

class(rat.data$sex) # 查看某列的类型
[1] “factor”

1
length(rat.data) # 查看数据框长度

length(rat.data) # 查看数据框长度
[1] 5

1
names(rat.data) # 数据框各项名称

names(rat.data) # 数据框各项名称
[1] “rats” “group” “sex” “glu.d1” “glu.d7”

1
2
summary(rat.data) 
# 数据框信息总结,对字符类/因子类数据,给出相应的频数统计;给数值型数据给出5个主要的指标

summary(rat.data)
rats group sex glu.d1 glu.d7
Min. :1.00 control:2 F:3 Min. : 5.190 Min. : 5.790
1st Qu.:2.25 model :2 M:3 1st Qu.: 8.085 1st Qu.: 7.885
Median :3.50 postive:2 Median :12.470 Median :13.470
Mean :3.50 Mean :14.705 Mean :14.742
3rd Qu.:4.75 3rd Qu.:21.220 3rd Qu.:21.470
Max. :6.00 Max. :27.340 Max. :25.560

1
2
table(rat.data$group,rat.data$sex) 
# 将数据框中的group与sex关联为一个表

table(rat.data$group,rat.data$sex)
F M
control 1 1
model 1 1
postive 1 1

数据框的去重

1
2
rat.data2 <- rbind(rat.data,rat.data) # 创建一个新数据框rat.data2,内容是rat.data的2倍
unique(rat.data2) # 对数据框进行去重,即提取不重复的元素

unique(rat.data2) # 对数据框进行去重,即提取不重复的元素
rats group sex glu.d1 glu.d7
1 1 postive F 11.97 12.97
2 2 postive M 12.97 13.97
3 3 model F 27.34 25.56
4 4 model M 23.97 23.97
5 5 control F 6.79 5.79
6 6 control M 5.19 6.19

去重函数unique()

查询数据中的唯一值只可以使用unique()函数,如下所示:

1
2
3
mtcars$cyl
unique(mtcars$cyl)
levels(as.factor(mtcars$cyl)) # 采用levles()这种方式只是核对一下,这种方式不推荐

结果如下所示:

1
2
3
4
5
6
> 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
> unique(mtcars$cyl)
[1] 6 4 8
> levels(as.factor(mtcars$cyl))
[1] "4" "6" "8"

取重复的行duplicated()

查找重复数据的函数是duplicated(),现在找出数据集iris中的一个重复值,如下所示:

1
2
3
4
5
6
7
8
x <- c(1, 2, 3, 3, 5, 4, 4, 5)
duplicated(x)
# 有重复的值就会标为TRUE,没有重复的值就标为FALSE
dupes <- duplicated(iris)
head(dupes)
which(dupes)
iris[dupes,]

计算结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> x <- c(1, 2, 3, 3, 5, 4, 4, 5)
> duplicated(x)
[1] FALSE FALSE FALSE TRUE FALSE FALSE TRUE TRUE
> # 有重复的值就会标为TRUE,没有重复的值就标为FALSE
> dupes <- duplicated(iris)
> head(dupes)
[1] FALSE FALSE FALSE FALSE FALSE FALSE
> which(dupes)
[1] 143
> iris[dupes,]
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
143 5.8 2.7 5.1 1.9 virginica

从上面结果可以看出来两个信息:

  1. 当duplicated()遇到重复的值时(重复的值必然至少有2个),第1个重复的值返回的是FALSE,到第2个以及第2个往后重复的值才显示为TRUE;
  2. duplicated()返回的是一个逻辑向量,因此可以将其当作索引去除重复行,如下所示:
1
2
head(iris[!dupes, ])
nrow(iris[!dupes, ])

计算结果如下所示:

1
2
3
4
5
6
7
8
9
10
> head(iris[!dupes, ])
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
> nrow(iris[!dupes, ])
[1] 149

再看一个案例:

1
rat.data2[duplicated(rat.data2),]# 取数据框中重复的行

rat.data2[duplicated(rat.data2),]# 取数据框中重复的行
rats group sex glu.d1 glu.d7
7 1 postive F 11.97 12.97
8 2 postive M 12.97 13.97
9 3 model F 27.34 25.56
10 4 model M 23.97 23.97
11 5 control F 6.79 5.79
12 6 control M 5.19 6.19

提取某个元素

rat.data[i,j]指第i行第j列的数据

1
rat.data[1,2] #取第1行第2列

rat.data[1,2] #取第1行第2列
[1] postive
Levels: control model postive

提取某行

1
2
rat.data[2,] #取第2行
rat.data[c(1,4),] #取1,4行

rat.data[2,] #取第2行
rats group sex glu.d1 glu.d7
2 2 postive M 12.97 13.97

rat.data[c(1,4),] #取1,4行
rats group sex glu.d1 glu.d7
1 1 postive F 11.97 12.97
4 4 model M 23.97 23.97

提取某列——用列号提取

1
rat.data[,3] #取第3列

rat.data[,3] #取第3列
[1] F M F M F M
Levels: F M

提取某列——用列名称提取

1
rat.data$rats #取rat.data数据框中的rats列

rat.data$rats #取rat.data数据框中的rats列
[1] 1 2 3 4 5 6

提取除掉某列的其余列

1
rat.data[,-3] #取除了第3列外的其余列

rat.data[,-3] #取除了第3列外的其余列
rats group glu.d1 glu.d7
1 1 postive 11.97 12.97
2 2 postive 12.97 13.97
3 3 model 27.34 25.56
4 4 model 23.97 23.97
5 5 control 6.79 5.79
6 6 control 5.19 6.19

取1到4行中的第4列

1
rat.data[1:4,4]

rat.data[1:4,4]
[1] 11.97 12.97 27.34 23.97

取1到4行中的第3列

1
rat.data[1:4,3]

rat.data[1:4,3]
[1] F M F M
Levels: F M

取第1行,2到4列

1
rat.data[1,2:4] #取第1行,2到4列

rat.data[1,2:4] #取第1行,2到4列
group sex glu.d1
1 postive F 11.97

提取满足某一条件的列==或match()

提取rat.data中所有control级别的观察值

1
2
3
Sel <- rat.data$group == "control"
rat.data.control <- rat.data[Sel,]
rat.data.control

rat.data.control
rats group sex glu.d1 glu.d7
5 5 control F 6.79 5.79
6 6 control M 5.19 6.19

使用match()函数,

在mtcars的行名称中检索Toyota Corolla元素,如下所示:

1
2
3
index <- match("Toyota Corolla", rownames(mtcars))
index
mtcars[index, 1:4]

计算结果如下所示:

1
2
3
4
5
6
> index <- match("Toyota Corolla", rownames(mtcars))
> index
[1] 20
> mtcars[index, 1:4]
mpg cyl disp hp
Toyota Corolla 33.9 4 71.1 65

使用with计算条件总和

案例:计算mtcars在不同马力段中油耗的平均值使用mean()函数,在阈值为150马力的情况下,计算过程如下所示:

1
2
3
with(mtcars, mean(mpg))
with(mtcars, mean(mpg[hp < 150]))
with(mtcars, mean(mpg[hp >= 150]))

结果如下所示:

1
2
3
4
5
6
> with(mtcars, mean(mpg))
[1] 20.09062
> with(mtcars, mean(mpg[hp < 150]))
[1] 24.22353
> with(mtcars, mean(mpg[hp >= 150]))
[1] 15.40667

提取子集案例二

如下所示:

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
> manager<-c(1,2,3,4,5)
> date<-c("10/24/08","10/28/08","10/01/08","10/12/08","05/01/09")
> country<-c("US","US","UK","China","UK")
> gender<-c("M","F","F","M","F")
> age<-c(32,45,25,23,99)
> q1<-c(5,3,3,2,1)
> q2<-c(4,5,4,4,5)
> q3<-c(2,4,3,4,3)
> q4<-c(5,3,3,NA,2)
> q5<-c(5,5,3,3,NA)
> leadership<-data.frame(manager,date,country,gender,age,q1,q2,q3,q4,q5,stringsAsFactors=FALSE)
> leadership
manager date country gender age q1 q2 q3 q4 q5
1 1 10/24/08 US M 32 5 4 2 5 5
2 2 10/28/08 US F 45 3 5 4 3 5
3 3 10/01/08 UK F 25 3 4 3 3 3
4 4 10/12/08 China M 23 2 4 4 NA 3
5 5 05/01/09 UK F 99 1 5 3 2 NA
> newdata <- leadership[, c(6:10)] #从leadership数据框中取第6行到第10行的变量,并且将其保存在newdata中,将行下标留空(,),表示取所有行
> newdata
q1 q2 q3 q4 q5
1 5 4 2 5 5
2 3 5 4 3 5
3 3 4 3 3 3
4 2 4 4 NA 3
5 1 5 3 2 NA

再看一案例,如下所示:

1
2
3
4
5
6
7
8
9
10
11
> leadership
manager date country gender age q1 q2 q3 q4 q5
1 1 10/24/08 US M 32 5 4 2 5 5
2 2 10/28/08 US F 45 3 5 4 3 5
3 3 10/01/08 UK F 25 3 4 3 3 3
4 4 10/12/08 China M 23 2 4 4 NA 3
5 5 05/01/09 UK F 99 1 5 3 2 NA
> newdata<- leadership[which(leadership$gender == "M" & leadership$age>30),] # 将leaderhip中30岁以上的男性选入newdata中
> newdata
manager date country gender age q1 q2 q3 q4 q5
1 1 10/24/08 US M 32 5 4 2 5 5

将某一数值转换为某一类别变量

创建数据框

1
2
3
4
5
6
7
8
9
10
11
12
13
manager<-c(1,2,3,4,5)
date<-c("10/24/08","10/28/08","10/1/08","10/12/08","5/1/09")
country<-c("US","US","UK","UK","UK")
gender<-c("M","F","F","M","F")
age<-c(32,45,25,39,99)
q1<-c(5,3,3,3,2)
q2<-c(4,5,5,3,2)
q3<-c(5,2,5,4,1)
q4<-c(5,5,5,NA,2)
q5<-c(5,5,2,NA,1)
leadership<-data.frame(manager,date,country,gender,age,q1,q2,q3,q4,q5,stringsAsFactor=FALSE)
#把字符转化为因子
leadership

leadership
manager date country gender age q1 q2 q3 q4 q5 stringsAsFactor
1 1 10/24/08 US M 32 5 4 5 5 5 FALSE
2 2 10/28/08 US F 45 3 5 2 5 5 FALSE
3 3 10/1/08 UK F 25 3 5 5 5 2 FALSE
4 4 10/12/08 UK M 39 3 3 4 NA NA FALSE
5 5 5/1/09 UK F 99 2 2 1 2 1 FALSE

转变变量(可转化为因子型变量)

要求:将大于99的转换为缺失,age大于75的为Elder,55到75之间的为Middle,55以下的为Young:

1
2
3
4
5
leadership$age[leadership$age == 99] <-NA # 年龄为99时,表示缺失
leadership$agecat[leadership$age >75] <- "Elder" # 当age大于75时,agecat为Elder
leadership$agecat[leadership$age >= 55 & leadership$age<= 75] <- "Middle" # 当55<= age <=75时,agecat为Middle
leadership$agecat[leadership$age < 55] <-"Young" #age<55时,agecat为Young
leadership

leadership
manager date country gender age q1 q2 q3 q4 q5 stringsAsFactor agecat
1 1 10/24/08 US M 32 5 4 5 5 5 FALSE Young
2 2 10/28/08 US F 45 3 5 2 5 5 FALSE Young
3 3 10/1/08 UK F 25 3 5 5 5 2 FALSE Young
4 4 10/12/08 UK M 39 3 3 4 NA NA FALSE Young
5 5 5/1/09 UK F NA 2 2 1 2 1 FALSE

判断数据框各行是否完整complete.cases

所用函数为complete.cases

1
2
3
rat.data1<-rat.data
rat.data1$group[2]<-NA
complete.cases(rat.data1) #判断数据框是否完整

complete.cases(rat.data1) #判断数据框是否完整
[1] TRUE FALSE TRUE TRUE TRUE TRUE

如果要删除某个数据集中的包含缺失值的行,那么就可以通过下面的代码实现:

1
2
3
4
rat.data1 <- rat.data1[complete.cases(rat.data1),]
# 或者是使用na.omit()函数
rat.data1 <- na.omit(rat.data1)

提取非缺失值

1
rat.data1[complete.cases(rat.data1),] #选择非缺失值的数据

rat.data1[complete.cases(rat.data1),] #选择非缺失值的数据
rats group sex glu.d1 glu.d7
1 1 postive F 11.97 12.97
3 3 model F 27.34 25.56
4 4 model M 23.97 23.97
5 5 control F 6.79 5.79
6 6 control M 5.19 6.19

增加列

直接添加

1
2
rat.data$result<-c(rat.data$glu.d1-rat.data$glu.d7)
rat.data

rat.data
rats group sex glu.d1 glu.d7 result
1 1 postive F 11.97 12.97 -1.00
2 2 postive M 12.97 13.97 -1.00
3 3 model F 27.34 25.56 1.78
4 4 model M 23.97 23.97 0.00
5 5 control F 6.79 5.79 1.00
6 6 control M 5.19 6.19 -1.00

cbind添加

格式为data.frame1 <- cbind(data.fram1,新的变量(可以由公式得到)),例如下面的例子就是在rat.data1添加一个result变量,result的变量是由rat.data1中的glu.d1减去glu.d7得到的。

1
2
rat.data1<-cbind(rat.data1, result=c(rat.data1$glu.d1-rat.data1$glu.d7))
rat.data1

rat.data1<-cbind(rat.data1, result=c(rat.data1$glu.d1-rat.data1$glu.d7))
rat.data1
rats group sex glu.d1 glu.d7 result
1 1 postive F 11.97 12.97 -1.00
2 2 M 12.97 13.97 -1.00
3 3 model F 27.34 25.56 1.78
4 4 model M 23.97 23.97 0.00
5 5 control F 6.79 5.79 1.00
6 6 control M 5.19 6.19 -1.00

另外的方法为:

1
2
3
rat.data1$result <- rat.data1$glu.d1-rat.data1$glu.d7
# 或
rat.data1 <- transform(rat.data1,result=glu.d1-glu.d7)

merge()添加

用法为total <- merge(dataframeA, dataframeB, by = "ID"),它表示,将dataframeA与dataframeB按照ID进行合并,这种联结通常是横向的,即向数据框中添加变量。

删除列

使用NULL

1
2
3
rat.data1
rat.data1$result<-NULL # 删除result这一列,原数列有2列result
rat.data1

rat.data1
rats group sex glu.d1 glu.d7 result
1 1 postive F 11.97 12.97 -1.00
2 2 M 12.97 13.97 -1.00
3 3 model F 27.34 25.56 1.78
4 4 model M 23.97 23.97 0.00
5 5 control F 6.79 5.79 1.00
6 6 control M 5.19 6.19 -1.00

rat.data1$result<-NULL # 删除result这一列

rat.data1
rats group sex glu.d1 glu.d7
1 1 postive F 11.97 12.97
2 2 M 12.97 13.97
3 3 model F 27.34 25.56
4 4 model M 23.97 23.97
5 5 control F 6.79 5.79
6 6 control M 5.19 6.19

用subset()

1
2
rat.data1<-subset(rat.data1,select=c(-sex,-group)) #删除sex,group列
rat.data1

rat.data1<-subset(rat.data1,select=c(-sex,-group)) #删除sex,group列
rat.data1
rats glu.d1 glu.d7
1 1 11.97 12.97
2 2 12.97 13.97
3 3 27.34 25.56
4 4 23.97 23.97
5 5 6.79 5.79
6 6 5.19 6.19

%in%

%in%是一种特殊类型的函数,被称为二元运算符。

使用%in%,如下所示:

先生成一个数据框,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> manager<-c(1,2,3,4,5)
> date<-c("10/24/08","10/28/08","10/01/08","10/12/08","05/01/09")
> country<-c("US","US","UK","China","UK")
> gender<-c("M","F","F","M","F")
> age<-c(32,45,25,23,99)
> q1<-c(5,3,3,2,1)
> q2<-c(4,5,4,4,5)
> q3<-c(2,4,3,4,3)
> q4<-c(5,3,3,NA,2)
> q5<-c(5,5,3,3,NA)
> leadership<-data.frame(manager,date,country,gender,age,q1,q2,q3,q4,q5,stringsAsFactors=FALSE)
> leadership
manager date country gender age q1 q2 q3 q4 q5
1 1 10/24/08 US M 32 5 4 2 5 5
2 2 10/28/08 US F 45 3 5 4 3 5
3 3 10/01/08 UK F 25 3 4 3 3 3
4 4 10/12/08 China M 23 2 4 4 NA 3
5 5 05/01/09 UK F 99 1 5 3 2 NA

现在删除q3与q4,如下所示:

1
2
3
4
5
6
7
8
9
> myvars <-names(leadership)%in%c("q3","q4")
> newdata<-leadership[!myvars]
> newdata
manager date country gender age q1 q2 q5
1 1 10/24/08 US M 32 5 4 5
2 2 10/28/08 US F 45 3 5 5
3 3 10/01/08 UK F 25 3 4 3
4 4 10/12/08 China M 23 2 4 3
5 5 05/01/09 UK F 99 1 5 NA

names(leadership)生成了一个包含所有变量名的字符型微量,即c("manager","date","country","gender","age","q1","q2","q3","q4","q5","stringsAsFactor"),names(leadership)%in%c("item3","item4")返回了一个逻辑型向量,names(leadership)``中每个匹配item3或item4的元素值为TRUE,反之为FALSE,c(FALSE, FALSE, FALSE, FALSE,FALSE, FALSE, FALSE, TRUE, TRUE, FALSE),运算符非(!)将逻辑值反转:c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE,FALSE, TRUE),leadership[c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE,TRUE)]`选择了逻辑值为TRUE的列,于是q3和q4被剔除了。

或者直接使用-号,如下所示:

1
2
3
4
5
6
7
8
> newdata <- leadership[c(-8,-9) ] #直接在变量前加减号
> newdata
manager date country gender age q1 q2 q5
1 1 10/24/08 US M 32 5 4 5
2 2 10/28/08 US F 45 3 5 5
3 3 10/01/08 UK F 25 3 4 3
4 4 10/12/08 China M 23 2 4 3
5 5 05/01/09 UK F 99 1 5 NA

增加行

1
2
rat.data1<-rbind(rat.data1,rat.data1)
rat.data1

rat.data1<-rbind(rat.data1,rat.data1)
rat.data1
rats glu.d1 glu.d7
1 1 11.97 12.97
2 2 12.97 13.97
3 3 27.34 25.56
4 4 23.97 23.97
5 5 6.79 5.79
6 6 5.19 6.19
7 1 11.97 12.97
8 2 12.97 13.97
9 3 27.34 25.56
10 4 23.97 23.97
11 5 6.79 5.79
12 6 5.19 6.19

删除行

1
2
rat.data1<-rat.data1[-8,] #删除第8行
rat.data1[-c(1,2),] #删除1,2行

rat.data1<-rat.data1[-8,] #删除第8行
rat.data1[-c(1,2),] #删除1,2行
rats glu.d1 glu.d7
3 3 27.34 25.56
4 4 23.97 23.97
5 5 6.79 5.79
6 6 5.19 6.19
7 1 11.97 12.97
9 3 27.34 25.56
10 4 23.97 23.97
11 5 6.79 5.79
12 6 5.19 6.19

数据框的排序

基于单列进行排序

排序所用的函数为sort()和order(),sort()是对元素直接进行排序,而order()则是反回排序后的元素在原来列中的位置,现在以内置的CO2数据为例说明,只取CO2的前10行:

1
2
3
4
5
6
7
8
9
raw_data <- CO2[1:10,]
raw_data
sort(raw_data$uptake) #对uptake进行排序,默认为升序
sort(raw_data$uptake,decreasing = TRUE) # decreasing为T时,为降序
order.raw_data <- order(raw_data$uptake);order.raw_data
# order的结果是说,在排序后的数据中,第1个元素位于原来的第8个位置
# 排序后的第1个数据是13.6,而13.6在原来uptake中位于第8
raw_data$uptake[order.raw_data] #这个结果与sort(raw_data$uptake)是一样的
raw_data[order.raw_data,] #按照uptake的升序对数据框进行排序

raw_data <- CO2[1:10,]
raw_data
Plant Type Treatment conc uptake
1 Qn1 Quebec nonchilled 95 16.0
2 Qn1 Quebec nonchilled 175 30.4
3 Qn1 Quebec nonchilled 250 34.8
4 Qn1 Quebec nonchilled 350 37.2
5 Qn1 Quebec nonchilled 500 35.3
6 Qn1 Quebec nonchilled 675 39.2
7 Qn1 Quebec nonchilled 1000 39.7
8 Qn2 Quebec nonchilled 95 13.6
9 Qn2 Quebec nonchilled 175 27.3
10 Qn2 Quebec nonchilled 250 37.1
sort(raw_data$uptake) #对uptake进行排序,默认为升序
[1] 13.6 16.0 27.3 30.4 34.8 35.3 37.1 37.2 39.2 39.7
sort(raw_data$uptake,decreasing = TRUE) # decreasing为T时,为降序
[1] 39.7 39.2 37.2 37.1 35.3 34.8 30.4 27.3 16.0 13.6
order.raw_data <- order(raw_data$uptake);order.raw_data
[1] 8 1 9 2 3 5 10 4 6 7

order的结果是说,在排序后的数据中,第1个元素位于原来的第8个位置

排序后的第1个数据是13.6,而13.6在原来uptake中位于第8

raw_data$uptake[order.raw_data] #这个结果与sort(raw_data$uptake)是一样的
[1] 13.6 16.0 27.3 30.4 34.8 35.3 37.1 37.2 39.2 39.7
raw_data[order.raw_data,] #按照uptake的升序对数据框进行排序
Plant Type Treatment conc uptake
8 Qn2 Quebec nonchilled 95 13.6
1 Qn1 Quebec nonchilled 95 16.0
9 Qn2 Quebec nonchilled 175 27.3
2 Qn1 Quebec nonchilled 175 30.4
3 Qn1 Quebec nonchilled 250 34.8
5 Qn1 Quebec nonchilled 500 35.3
10 Qn2 Quebec nonchilled 250 37.1
4 Qn1 Quebec nonchilled 350 37.2
6 Qn1 Quebec nonchilled 675 39.2
7 Qn1 Quebec nonchilled 1000 39.7

基于多列的排序

还以前述的数据为例说明:

1
2
3
4
5
order.raw_data2 <- with(raw_data,order(conc,uptake))
raw_data[order.raw_data2,]
order.raw_data3 <- with(raw_data,order(uptake,conc))
raw_data[order.raw_data3,]

order.raw_data2 <- with(raw_data,order(conc,uptake))
raw_data[order.raw_data2,]
Plant Type Treatment conc uptake
8 Qn2 Quebec nonchilled 95 13.6
1 Qn1 Quebec nonchilled 95 16.0
9 Qn2 Quebec nonchilled 175 27.3
2 Qn1 Quebec nonchilled 175 30.4
3 Qn1 Quebec nonchilled 250 34.8
10 Qn2 Quebec nonchilled 250 37.1
4 Qn1 Quebec nonchilled 350 37.2
5 Qn1 Quebec nonchilled 500 35.3
6 Qn1 Quebec nonchilled 675 39.2
7 Qn1 Quebec nonchilled 1000 39.7

order.raw_data3 <- with(raw_data,order(uptake,conc))
raw_data[order.raw_data3,]
Plant Type Treatment conc uptake
8 Qn2 Quebec nonchilled 95 13.6
1 Qn1 Quebec nonchilled 95 16.0
9 Qn2 Quebec nonchilled 175 27.3
2 Qn1 Quebec nonchilled 175 30.4
3 Qn1 Quebec nonchilled 250 34.8
5 Qn1 Quebec nonchilled 500 35.3
10 Qn2 Quebec nonchilled 250 37.1
4 Qn1 Quebec nonchilled 350 37.2
6 Qn1 Quebec nonchilled 675 39.2
7 Qn1 Quebec nonchilled 1000 39.7

可以看出来,在第1种排序中, with(raw_data,order(conc,uptake)),先以order进行排序,如果order相同,则按照uptake进行排序;在第2种排序中,with(raw_data,order(uptake,conc)),先以uptake进行排序,如果uptake相同,则按conc进行排序。

混合排序

混合排序是指某一列是升序,某一列为降序,所用到的函数是xtfrm(),其中在需要降序的列前加上铅,在升序的列前加正号,现在以raw_data数据为例说明,以conc的降序,uptake的升序进行排序,用法如下:

1
2
order.raw_data4 <- order(-xtfrm(raw_data$conc),+raw_data$uptake)
raw_data[order.raw_data4,]

order.raw_data4 <- order(-xtfrm(raw_data$conc),+raw_data$uptake)
raw_data[order.raw_data4,]
Plant Type Treatment conc uptake
7 Qn1 Quebec nonchilled 1000 39.7
6 Qn1 Quebec nonchilled 675 39.2
5 Qn1 Quebec nonchilled 500 35.3
4 Qn1 Quebec nonchilled 350 37.2
3 Qn1 Quebec nonchilled 250 34.8
10 Qn2 Quebec nonchilled 250 37.1
9 Qn2 Quebec nonchilled 175 27.3
2 Qn1 Quebec nonchilled 175 30.4
8 Qn2 Quebec nonchilled 95 13.6
1 Qn1 Quebec nonchilled 95 16.0

R语言笔记之数据类型2因子

发表于 2017-04-02 | 分类于 R
| 字数统计: 2,076 | 阅读时长 ≈ 10

因子

因子定义

因子(factor):是名义型变量或有序型变量,比较特殊。一个因子不仅包括分类变量本身还包括变量不同的可能水平(即使它们在数据中不出现)。

factor()用法

factor (x,levels=sort(unique(x),na.last=TRUE), labels=lebels, exclude=NA, ordered=is.order (x))

其中,levels用于指定因子的可能水平,labels用于定义水平的名字;exclude指从向量x中剔除的水平值,ordered指因子的水平是否要排序,例如:

1
2
3
4
a <- factor(1:3)
a
## [1] 1 2 3
## Levels: 1 2 3

从上面的结果可以看出,这组数据中有3个数据,3个水平,分别为1,2,3。还有一种情况是,水平数大于实际的数据数,如下所示:

1
2
3
b<-factor(1:3,levels=1:5);b
## [1] 1 2 3
## Levels: 1 2 3 4 5

这组数据中有3个数据,有5个水平(其中两个水平没出现)。

factor数据的名称

1
2
3
4
5
6
c<-factor(1:3,labels=c("a","b","c"))
c
## [1] a b c
## Levels: a b
> str(c)
Factor w/ 3 levels "a","b","c": 1 2 3

c有三个水平,名字分别为a,b,c

将factor转化为其它类型

数值型

1
2
3
4
5
6
7
8
9
10
11
d<-c(1,10) #建立向量a,值为1,10
d
## [1] 1 10
fac<-factor(d)
fac #提取向量a的因子数,并赋给fac
## [1] 1 10
## Levels: 1 10
fac_value<-as.numeric(fac) #将fac转化为数值
fac
## [1] 1 10
## Levels: 1 10

字符型

1
2
3
4
5
6
7
8
9
e<-c("Male","Female")
e #建立向量e,为字符型
## [1] "Male" "Female"
fac_e<-factor(e);fac_e #提取向量b的因子,并且赋给fac2
## [1] Male Female
## Levels: Female Male
fac_e_value<-as.numeric(fac_e)#将fac_e转化为数值型
fac_e_value
## [1] 2 1

将factor转换为数值

1
2
as.numeric(as.character(fac))
## [1] 1 10

上述命令将fac(1,10)先转化为字符型,接着将字符型转化为数值型,如果直接将factor转换为numeric,容易出错,一般情况下就是先看factor转换为character,再转换为numeric。

将其它数据转换为factor

将字符转换为因子

1
2
3
4
5
6
7
8
9
a <- c("green","blue","green","yellow")
a <- factor(a)
levels(a) <- c(1,2,3,4)
ff <- factor(c("A","B","C",labels=c(1,2,3)))
ff
## labels1 labels2 labels3
## A BC 1 23
## Levels: 1 2 3 A B C

将数值转换为因子

1
2
3
4
5
6
b <- c(1,2,3,1)
b <- factor(b)
b
## [1] 1 2 3 1
## Levels: 1 2 3

提取可能的factor

1
2
3
4
5
6
7
8
9
ff <- factor(c(2,4),levels=2:5)
ff
## [1] 2 4
## Levels: 2 3 4 5
levels(ff)
## [1] "2" "3" "4" "5"

将连续型数据转换factor

以PlantGrowth数据集为例说明,先看一下这个数据集:

1
2
3
4
5
6
7
8
pg <- PlantGrowth[c(1,2,11,21,22),]
pg
# weight group
# 1 4.17 ctrl
# 2 5.58 ctrl
# 11 4.81 trt1
# 21 6.31 trt2
# 22 5.12 trt2

在这个案例中,我们使用cut()函数把一个连续型变量weight转化为分类变量wtclass,如下所示:

1
2
3
4
5
6
7
8
pg$wtclass <- cut(pg$weight,breaks=c(0,5,6,Inf))
pg
# weight group wtclass
# 1 4.17 ctrl (0,5]
# 2 5.58 ctrl (5,6]
# 11 4.81 trt1 (0,5]
# 21 6.31 trt2 (6,Inf]
# 22 5.12 trt2 (5,6]

我们为三个类设定了四个边界值,边界值可以包括正无穷(Inf)和负无穷(-Inf),如果一个值落在我们规定的区间外,它的类别将被设定为NA(缺失值),cut()函数的结果是一个因素,并且因子水平的名称是以生成的区间命名的,如下所示:

1
2
3
4
5
> str(pg)
'data.frame': 5 obs. of 3 variables:
$ weight : num 4.17 5.58 4.81 6.31 5.12
$ group : Factor w/ 3 levels "ctrl","trt1",..: 1 1 2 3 3
$ wtclass: Factor w/ 3 levels "(0,5]","(5,6]",..: 1 2 1 3 2

但是这个区间名称明显不太方便,我们可以更改一下,如下所示:

1
2
3
4
5
6
7
8
9
pg$wtclass <-cut(pg$weight,breaks=c(0,5,6,Inf),
labels=c("Small","Medium","Large"))
# > pg
# weight group wtclass
# 1 4.17 ctrl Small
# 2 5.58 ctrl Medium
# 11 4.81 trt1 Small
# 21 6.31 trt2 Large
# 22 5.12 trt2 Medium

cut()函数生成的区间是左开右闭的,换句话说,它们不会包含最小值,但是它们包含了最大值,对于值最小的一类,可以通常设置参数include.lowest=TRUE来实现,这样它们就能同时包含最小值和最大值了,如果要让生成的区间是左闭右开的,需要设定参数right=FALSE,如下所示:

1
pg$wtclass <- cut(pg$weight,breaks=c(0,5,6,Inf),right=FALSE)

如果要更改不同因子的名称,例如将Small改为A,Medium改为B,Large改为C,那么就需要car中的recode函数,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
head(pg)
# weight group wtclass
# 1 4.17 ctrl Small
# 2 5.58 ctrl Medium
# 11 4.81 trt1 Small
# 21 6.31 trt2 Large
# 22 5.12 trt2 Medium
library(car)
pg$wtclass <- recode(pg$wtclass,"'Small'='A';'Medium'='B';'Large'='C'")
head(pg)
# weight group wtclass
# 1 4.17 ctrl A
# 2 5.58 ctrl B
# 11 4.81 trt1 A
# 21 6.31 trt2 C
# 22 5.12 trt2 B

生成指定的factor

seq()

在R的向量笔记中,提到了seq()函数用来生成某一条件的向量,这个函数在生成特定因子方面也有很重要的作用,用法为seq(length=, from=, to=),其中,length:指定生成个数,from:是指开始生成的点,to:截止点。如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
seq(length=10,from=10,to=100) # 生成从10到100的向量,一共10个
## [1]10 20 3040 50 6070 80 90 100
# 上述命令等价于
seq(10,100,10)
## [1]10 20 3040 50 6070 80 90 100
seq(1,10,by=2)
## [1] 1 3 5 7 9
seq(1,10,length=6)
## [1] 1.02.8 4.6 6.48.2 10.0
sequence(2:3) #产生以 2 和 3 结尾的序列数据
## [1] 1 2 1 2 3

rep()

用法:rep(P,N),表示重复生成P值N次,例如rep(a1:a2,a1:a2) #重复a1到a2,按a1产生a1次,按a2产生a2次,如下所示:

1
2
3
4
5
6
7
8
rep(1,10)
## [1] 1 1 1 1 1 1 1 1 1 1
rep(1:5,each=2, times=2) #重复1到5,每个元素重复二次,整个数列重复两次
## [1] 1 1 2 2 3 3 4 4 5 5 1 1 2 2 3 3 4 4 5 5
rep(1:3,1:3) # 1重复1次,2重复2次,3重复3次
## [1] 1 2 2 3 3 3

gl函数

生成规则的因子序列,gl(k,n):k为水平数据,n是每个水平重复的次数。如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
gl(3,5) #生成5个1,5个2,5个3,
## [1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
## Levels: 1 2 3
gl(3,5,length=30) #生成5个1,5个2,5个3,循环到30个,即:
## [1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
## Levels: 1 2 3
gl(2,6,label=c("Male","Female")) #生成Male与Female两个因子,各6个,共12个数据:
## [1] MaleMale Male MaleMale Male Female Female Female Female
## [11] Female Female
## Levels: Male Female

有序因子

因子没有顺序,但也可以人为指定顺序。例如糖尿病类型Diabetes(Type1,Type2),就是2种类型没有顺序,但病人状态status(Poor,Imporved,Excellent)是有顺序的。案例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
patientID<-c(1,2,3,4)
age<-c(25,34,28,52)
diabetes<-c("Type1","Type2","Type1","Type1")
status<-c("Poor","Improved","Excellent","Poor")
diabetes<-factor(diabetes) #提取不同糖尿病类型的因子
status<-factor(status,order=TRUE) # 提取因子,并且有序
patientdata<-data.frame(patientID,age,diabetes,status)
patientdata
## patientID age diabetes status
## 11 25 Type1Poor
## 22 34 Type2Improved
## 33 28 Type1 Excellent
## 44 52 Type1Poor

注:字符型向量的因子水平默认依字母顺序创建。但在实际情况中并不常用,而是通过levels选项来指定因子顺序,使用factor(status, order = TRUE, levels = c(“Poor”, “Improved”, “Excellent”)),各个水平的赋值就为1 = Poor, 2 = Improved, 3 = Excellent。或者是通过下面代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
factor(status, ordered = TRUE, levels = c("Poor", "Improved", "Excellent"))
## [1] Poor ImprovedExcellent Poor
## Levels: Poor < Improved < Excellent
str(patientdata)#显示数据框的结构
## 'data.frame': 4 obs. of 4 variables:
## $ patientID: num 1 2 3 4
## $ age : num25 34 28 52
## $ diabetes : Factor w/ 2 levels "Type1","Type2": 1 2 1 1
## $ status : Ord.factor w/ 3 levels "Excellent"<"Improved"<..: 3 2 1 3
summary(patientdata)
## patientID age diabetes status
## Min. :1.00Min. :25.00 Type1:3Excellent:1
## 1st Qu.:1.75 1st Qu.:27.25 Type2:1Improved :1
## Median :2.50 Median :31.00 Poor :2
## Mean :2.50Mean :34.75
## 3rd Qu.:3.25 3rd Qu.:38.50
## Max. :4.00Max. :52.00

factor的统计

如果一组数据有多个重复值,例如美国的每一个州都位于4个区域的中某一个,分别为东北,南、中北和西,则我们看一下内置的state数据集:

1
2
3
4
5
6
7
8
9
10
head(state.region)
## [1] South West West South WestWest
## Levels: Northeast South North Central West
table(state.region)
## state.region
##Northeast South North Central West
##9 16 12 13

R语言笔记之数据类型之向量

发表于 2017-04-01 | 分类于 R
| 字数统计: 3,011 | 阅读时长 ≈ 14

常见数据类型

R拥有许多用于存储数据的对象类型,包括标量、向量、矩阵、数组、数据框和列表。它们在存储数据的类型、创建方式、结构复杂度,以及用于定位和访问其中个别元素的标记等方面均有所不同。下图给出了这些数据结构的一个示意图:

查看数据类型

class()

使用class函数可以查看数据的类型,如下所示:

1
2
3
4
5
6
> x=c(1,2,3,4)
> class(x)
[1] "numeric"
> x1<-as.character(x)
> class(x1)
[1] "character"

数据类型转换

常用函数如下所示:

1
2
3
4
5
6
7
8
判断转换 类型转换函数
is.numeric() as.numeric()
is.character() as.character()
is.vector() as.vector()
is.matrix() as.matrix()
is.data.frame() as.data.frame()
is.factor() as.factor()
is.logical() as.logical()

使用如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> a <- c(1,2,3);a
[1] 1 2 3
> is.numeric(a)
[1] TRUE
> is.vector(a)
[1] TRUE
> a <- as.character(a)
> a #将a转化为字符串类型
[1] "1" "2" "3"
> is.numeric(a)
[1] FALSE
> is.vector(a)
[1] TRUE
> is.character(a)
[1] TRUE
> as.numeric(FALSE) #逻辑型数据转化为0与1
[1] 0
> as.numeric(TRUE)
[1] 1

向量

常见向量类型

向量可以是数值,字符,逻辑等,如下所示:

1
2
3
4
5
6
7
8
9
10
> a<-c(1,2,3,4,5,-3,-4);a #数值型向量
[1] 1 2 3 4 5 -3 -4
> b<-c("one","two","three");b #字符型向量
[1] "one" "two" "three"
> c<-c(TRUE,TRUE,TRUE,FALSE);c #逻辑型向量
[1] TRUE TRUE TRUE FALSE
> x<-c(5,4,2);x
[1] 5 4 2
> x[9]<-9;x # 当向量x不够长时,指定第9个元素为9,#自动将中间的元素补为NA
[1] 5 4 2 NA NA NA NA NA 9

向量的下标

向量的元素下标取值是以1开始,例如:要前例中取x向量中值为1,则为x[2],如果一个向量中有一个字符,则该向量的类型会变成字符,如下所示:

1
2
3
4
5
> demo_1<-c(1,2,'a')
> demo_1
[1] "1" "2" "a"
> mode(demo_1)
[1] "character"

向量的名称

1
2
3
4
5
6
> years <- c(1960,1964,1976,1994)
> years
[1] 1960 1964 1976 1994
> names(years)<-c("Kennedy", "Johnson", "Carter","Clinton");years
Kennedy Johnson Carter Clinton
1960 1964 1976 1994

向量元素的添加及合并

常用函数为c(),append(),如下所示:

1
2
3
4
5
6
7
8
9
10
v1<-c(1,2,3);v1
v1_ft <- c(TRUE, TRUE, FALSE)
v1[v1_ft]
v2<-c(v1,55);v2
#格式为新向量<-(原向量,新元素)
## [1] 12 3 55
c(v2,v1) # 向量的合并
## [1] 12 3 55 12 3
append(v1,10,after=3) #在第3个向量后面加入10
## [1] 12 3 10

运行结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
> v1<-c(1,2,3);v1
[1] 1 2 3
> v1_ft <- c(TRUE, TRUE, FALSE)
> v1[v1_ft]
[1] 1 2
> v2<-c(v1,55);v2
[1] 1 2 3 55
> c(v2,v1) # 向量的合并
[1] 1 2 3 55 1 2 3
> ## [1] 12 3 55 12 3
> append(v1,10,after=3) #在第3个向量后面加入10
[1] 1 2 3 10

如果逻辑变量与数值在一起,则为转换成数值。TRUE转变成1 and FALSE 转变成 0,如下所示:

1
2
3
4
> demo_2<-c(1,2,TRUE);demo_2
[1] 1 2 1
> mode(demo_2)
[1] "numeric"

在R语言中没有单一的整数、单一字符的概念,例如:X<-2;X<-'a';R都是当作向量来处理,只是这个向量只包括单一值。

向量批量序列的生成

seq()

用法:seq(length=, from=, to=)

length:指定生成个数;from:是指开始生成的点;to:截止点。如果不指定,则默认条件下:seq(N1,N2,BY=),其中,n1:开始位置;n2:截止位置;by=指定间隔,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
seq(length=10,from=10,to=100) # 生成从10到100的向量,一共10个
## [1]10 20 3040 50 6070 80 90 100
# 此命令等价于:
seq(10,100,10)
## [1]10 20 3040 50 6070 80 90 100
seq(1,10,by=2)
## [1] 1 3 5 7 9
seq(1,10,length=6)
## [1] 1.02.8 4.6 6.48.2 10.0
sequence(2:3) #产生以 2 和 3 结尾的序列数据
## [1] 1 2 1 2 3

rep()

用法:1. rep(P,N) 重复生成P值N次;2.rep(a1:a2,a1:a2) #重复a1到a2,按a1产生a1次,按a2产生a2次,如下所示:

1
2
3
4
5
6
rep(1,10)
## [1] 1 1 1 1 1 1 1 1 1 1
rep(1:5,each=2, times=2) #重复1到5,每个元素重复二次,整个数列重复两次
## [1] 1 1 2 2 3 3 4 4 5 5 1 1 2 2 3 3 4 4 5 5
rep(1:3,1:3) # 1重复1次,2重复2次,3重复3次
## [1] 1 2 2 3 3 3

向量索引

取子向量:通过下标实现

取某个元素:x[2];(如果X包括名称,注意:x[2]与x[[2]]的区别;

取某中几个:x[c(1,2,0)]

取某个/几个元素,利用-:x[-n]

向量排序

sort(); 输出排序后的结果;order();输出排序后的各个向量位置,如下所示:

1
2
3
4
5
6
a<-c(3,9,0,12,19)
sort(a)
## [1] 03 9 12 19
order(a)
## [1] 3 1 2 4 5
a<-c(3,9,0,12,19)

向量运算

相加

1
2
3
4
5
6
7
8
9
> Demo_5 <- 1:3;Demo_5
[1] 1 2 3
> Demo_6 <- 2:5;Demo_6
[1] 2 3 4 5
> Demo_7 <- Demo_6+ Demo_5;Demo_7
Warning message:
In Demo_6 + Demo_5 :
longer object length is not a multiple of shorter object length
[1] 3 5 7 6

向量:提取满足某一条件的向量

常见用法如下所示:

1
2
3
4
5
6
7
8
9
x[n] 第n个元素
x[-n] 除了第n个元素的x
x[1:n] 前n个元素
x[-(1:n)] 第n+1至最后的元素
x[c(1,4,2) ] 指定元素
x["name"] 名为"name"的元素
x[x > 3] 所有大于3的元素
x[x > 3 & x < 5] 区间(3,5)的元素
x[x %in% c ("a","and","the")] 给定组中的元素

具体案例使用如下所示:

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
x<-c(10:1);x
## [1] 109 8 76 5 43 2 1
x[x==3]<-25;x #将x中等于3的元素变为25
## [1] 109 8 76 5 4 252 1
x[x=1]<-12;x #将x的第1个元素数值变为12
## [1] 129 8 76 5 4 252 1
letters[1:30] # 产生字母序列
## [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q"
## [18] "r" "s" "t" "u" "v" "w" "x" "y" "z" NA NA NA NA
a <- c(2,3,4,2,5,1,6,3,2,5,8,5,7,3);a
## [1] 2 3 4 2 5 1 6 3 2 5 8 5 7 3
which.max(a) # 找出最大元素的下标
## [1] 11
which.min(a) # 找出大小的元素下标
## [1] 6
a[which.max(a)] # 找出最大的元素
## [1] 8
which(a==2) # 等于2的元素的下标
## [1] 1 4 9
a[which(a==2)] # 等于2的元素
## [1] 2 2 2
which(a>5) # 大于5的元素的下标
## [1] 7 11 13
a[which(a>5)] # 大于5的元素
## [1] 6 8 7

再看一案例

1
2
3
4
5
6
7
> data <- 1:100
> data[data > 20]
# 取data 中大于20 的对象出来
[1] 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
[25] 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
[49] 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
[73] 93 94 95 96 97 98 99 100

通过方括号中的data > 20 ,实现了我们想要的效果,具体是如何实现的呢?

1
2
3
4
5
6
7
8
> data > 20
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[17] FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[33] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[49] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[65] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[81] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[97] TRUE TRUE TRUE TRUE

data > 20 是一个表示式,它的返回值是一个有TRUE和FALSE 构成的逻辑向量,最终只选取了TRUE对应的元素,所以data 中大于20的元素被选了出来。通过下标和逻辑值两种方式,可以满足我们绝大部分的需求,但是有时候,我们只是想知道符合条件的值对应的下标,这个时候which 函数就派上了用场,如下所示:

1
2
> which(letters == "a")
[1] 1

==操作符用来判断字符串相等,which 函数返回对应的下标,letters 这个向量中,第一个元素就是字母a, 所以返回值为1,如下所示:

1
2
3
4
5
> letters
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x"
[25] "y" "z"
> which(letters %in% c("a", "d", "e"))
[1] 1 4 5

%in%操作符用来判断操作符左边的向量中的元素是否位于操作符右边的向量中,通过这种集合操作,可以方便的一次返回多个下标,使用subset函数也可以提取满足某一条件的向量元素,如下所示:

1
2
3
4
5
> x <- c(1,3,8,2,20)
> x
[1] 1 3 8 2 20
> subset(x,x>5)
[1] 8 20

ifelse

1
2
3
4
> x <- c(1,1,1,0,0,1,1);x
[1] 1 1 1 0 0 1 1
> ifelse(x != 1, 1, 0) #若果x的值不等于1,输出1,否则输出0
[1] 0 0 0 1 1 0 0

ifelse和%in%的联合使用,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> ifelse(x %in% 1, 1, 0) #若x的值包含在1里面,输出1,否者输出0
[1] 1 1 1 0 0 1 1
> ifelse(x %in% 1, 'yes', 'no') #若x的值包含在1里面,输出yes,否者输出no
[1] "yes" "yes" "yes" "no" "no" "yes" "yes"
> which(x %in% 1) # 输出x包含在1中值的位置
[1] 1 2 3 6 7
> y <- c(2, 1, 3, 4)
> z <- c(1, 4)
> ifelse(y %in% z, which(y==z), 0 ) ##若y的值包含在z里面,输出y==z的位置,否者输出0
[1] 0 4 0 4
> ifelse(y %in% z, which(y==z), 0 ) ##若y的值包含在z里面,输出y==z的位置,否者输出0,
[1] 0 4 0 4
> #此例中没有找到y==z的值, 输出为NA。
> ifelse(y %in% z, 1, 0 )
[1] 0 1 0 1

向量的比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
x<-c(1,2,3)
y<-c(1,2,3)
z<-c(1,2,4);
x;y;z
## [1] 1 2 3
## [1] 1 2 3
## [1] 1 2 4
x==y;x==z;y==z #分别比较x,y,z的各个元素
## [1] TRUE TRUE TRUE
## [1] TRUETRUE FALSE
## [1] TRUETRUE FALSE
identical(x,y);identical(x,z);identical(z,y) #比较x,y,z的整体
## [1] TRUE
## [1] FALSE
## [1] FALSE
all.equal(x,y) #比较数值型变量是否“近似相等”
## [1] TRUE

两组数据的集合运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
> #首先对集合A,B,C赋值
> A<-1:10
> B<-seq(5,15,2)
> C<-1:5
> union(A,B)#求A和B的并集
[1] 1 2 3 4 5 6 7 8 9 10 11 13 15
> intersect(A,B) #求A和B的交集
[1] 5 7 9
> setdiff(A,B) #求A-B
[1] 1 2 3 4 6 8 10
> setdiff(B,A) #求B-A
[1] 11 13 15
> setequal(A,B) # 检验集合A,B是否相同
[1] FALSE
> is.element(12,C) #检验元素12是否属于集合C
[1] FALSE
> all(C%in%A) #检验集合A是否包含C
[1] TRUE
> all(C%in%B)
[1] FALSE
> match(C,B)
[1] NA NA NA NA 1

从上面可以看到%in%这个操作符只返回逻辑向量TRUE 或者FALSE,而且返回值应该与%in%这个操作符前面的向量程度相等。也就是说它相当于遍历了C里面的一个个元素,判断它们是否在B中出现过,然后返回是或者否即可。而match(C,B)的结果就很不一样了,它的返回结果同样与前面的向量等长,但是它并非返回逻辑向量,而是遍历了C里面的一个个元素,判断它们是否在B中出现过,如果出现就返回在B中的索引号,如果没有出现,就返回NA,还来看一个match()的案例,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
A<-1:10
B<-seq(5,15,2)
C<-1:5
A
B
C
match(A,B) #遍历A中的元素,看A的元素是否在B里面出现过,如果A中的元素在B中出现,就返回此元素在B中的索引号
match(B,A)
match(A,C)
match(C,A)
match(B,C)
match(C,B)

运行结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> A
[1] 1 2 3 4 5 6 7 8 9 10
> B
[1] 5 7 9 11 13 15
> C
[1] 1 2 3 4 5
> match(A,B)
[1] NA NA NA NA 1 NA 2 NA 3 NA
> match(B,A)
[1] 5 7 9 NA NA NA
> match(A,C)
[1] 1 2 3 4 5 NA NA NA NA NA
> match(C,A)
[1] 1 2 3 4 5
> match(B,C)
[1] 5 NA NA NA NA NA
> match(C,B)
[1] NA NA NA NA 1
1…2425

RVDSD

249 日志
14 分类
118 标签
© 2019 RVDSD
本站访客数:
由 Hexo 强力驱动
|
豫公网安备 41018102000118
主题 — NexT.Pisces v5.1.3
博客全站共981.6k字