Contents
- 基本操作
- R包安装
- R包使用
- 帮助文档
- 内置数据集
- R数据结构
- 向量 vector
- 矩阵 matrix
- 列表
- 数据框
- 因子 factor
- 缺失数据
- 字符串
- 日期和时间
- 获取数据
- 读入文件
- 写入文件
- 读写Excel文件
- 读写R格式文件
- 数据转换
- 数据转换 - reshape2包
- 数据转换 - tidyr包
- 数据转换 - dplyr包
【参考课程】R语言入门与数据分析-基因学苑
基本操作
getwd()
:显示目前软件默认使用的工作目录setwd(dir = " D:/目录/文件夹 ")
:设置默认的工作目录,注意用反斜线list.files()
or dir()
:查看工作目录下方文件x <- 3
or 3->x
or x=3
:赋值,但后两种不建议使用,易混淆x << 3
:强制赋值给全局变量,而不是局部变量ls()
,ls.str()
,str()
:查看已有变量,查看已有变量及其具体内容,查看变量具体内容rm()
:删除空间中的变量,无法恢复rm(list = ls())
:删除空间中所有变量save.image()
:保存工作空间,防止意外退出
Ctrl+L:清空屏幕
解决R错误问题的渠道推荐:Google, Rblogger, quickR, stackoverflow, etc.
R包安装
install.packages("包")
:安装R包,记得加引号,否则会以为是变量.libPaths()
:查看库所在的位置library()
:查看库里有那些软件包
有依赖包时:
https://www.bilibili.com/video/BV19x411X7C6?p=11&share_source=copy_web&vd_source=b2f5129a4c67d099a5616e4c249193c1
R包使用
R基础软件包:base, datasets, utils, grDevices, graphics, stats, methods, splines, stats4, tcltkrequire(包):
加载包help(package = "包")
:查看包的帮助文档library(help = "包")
:查看包的默认数据集和函数ls("package:包"):
列出包中所有包含的函数data(package="包"):
列出包中所有包含的数据集detach("package:包"):
将包从内存中移除,需要使用时要重新加载remove.packages("包"):
将包从电脑彻底删除
R包的批量移植方法之一:
installed.packages() # 提取目前环境中已安装的包
installed.packages()[,1] # 提取第一列,即R包的名字
save(Rpack, file="Rpack.Rdata") # 将提取的R包名字保存到一个文件中
###然后将该文件复制到新设备
###在新设备上load该文件,仍然以Rpack命名
for(i in Rpack) install.packages(i) # 用循环语句在新设备上批量安装R包
帮助文档
help.start()
:获取帮助文档help(函数)
or ?函数
:获取具体函数的帮助文档args(函数)
:返回具体函数需要的输入参数example(函数)
:返回具体函数的使用示例help(package = 包)
:获取具体包的帮助文档vignette(包)
:获取具体包的vignette文档,含有简介、开发等详细内容??函数
:不用安装包也可以获取相应的帮助文档??"特殊符号"
:获取特殊符号的帮助文档help.search("关键字")
:模糊搜索帮助文档apropos("关键字", mod = "function")
:返回所有包含关键字的内容,用于模糊搜索,可以指定mod筛选出类型(function/package/…)RSiteSearch("关键字")
:在官网模糊搜索帮助文档
基于Google的专门搜索R语言相关的搜索网站:Rseek.org
内置数据集
Notes:数据集的名字都是给定的,如果我们给变量的时候重复了,内置数据集就会被替换掉,不过没关系,再用data("数据集")
重新加载就好了。help(package="datasets")
:查看帮助文档data()
:返回内置的所有数据集,默认页面左边是数据集名字,右边是详细介绍data(package="包")
:列出包含有的数据集data(package=.packages(all.available=TRUE))
:显示R中所有可用的数据集data(数据集, package="包")
:不加载包而直接调用包里的数据集mode(变量名)
:返回变量类型
R数据结构
向量 vector
创建向量
向量,是用于存储数值型、字符型或逻辑型数据的一维数组。是构成其他数据结构的基础。
用函数c来创建向量,c代表连接concatenate,也可以理解为收集collect,或合并combine。x <- c(1,2,3,4,5)
,x <- c("one","two")
:创建一个数组{1,2,3,4,5},{one, two}并赋值给x
Note:字符串必须加引号(不加引号默认为对象object,就会直接在工作空间里面找)
Note:数值型和字符型变量混合建立向量时,数值型会自动转化为字符型变量
创建等差数列c(1:100)
or seq(from=1, to=100)
:创建1~100等差数列,等差值默认为1seq(from=1, to=100, by=2)
:创建1~100差值为2的等差数列seq(from=1, to=100, length.out=10)
:创建1~100含10个元素的等差数列
创建重复元素的数列rep(x, each=3, times=2)
:重复x两次,每次各元素重复三次,(e.g. x={1,2,3},111222333111222333)rep(x, c(2,4,6,1,3))
:用向量c(2,4,6,1,3)设置向量x中各元素的重复次数
筛选向量元素x[x>3]
:在数值型向量x中筛选出大于3的元素
向量索引
- 正(负)整数索引
length(向量)
:返回向量的元素个数x[1]
:返回向量x的第一个元素x[-10]
:返回向量x除了第十个元素的其他所有元素x[c(4:18)]
:返回向量x第4~18个元素,别忘了向量要用c喔,也可以返回任意指定位置的元素 - 逻辑向量索引
x[c(T,T,T,F,F,T)]
:返回向量x中,对应[ ]内向量逻辑值为正的位置的元素。若[ ]内的逻辑向量的元素偏少,则会循环至与向量x相同长度;反之,则会显示NA表示缺失值x[x<2 & x>5]
:也可以用逻辑运算符,依次返回符合条件的元素"one" %in% c("one", "two")
:返回TRUE("one"在向量c(“one”, “two”)中)c("one", "two") %in% "one"
:返回TRUE,FALSE("one"在c(“one”)中,而"two"不在)z[z %in% c("one", "two")]
:返回TRUE对应位置的向量z中元素(即在c(“one”, “two”)中的元素) - 名称索引
names(x) <- c("one", "two", "three", "four", "five")
:给向量x各元素定义名字,然后就可以通过名字访问对应元素,类似于表头的作用
向量增删元素x[4] <- 4
:假设原来x只有三个元素,这样就直接在后面增添了一个元素4;如果原来x只有两个或更少的元素,这样在中间就会出现很多NA表示缺失值append(x = 被插入的向量, values = 插入值, after = 插入位置-1)
:在中间插入元素x[-c(2,3)]
:返回除了第2~3个元素的其他元素x <- x[-c(2,3)]
:实现了删除第2~3个元素x["two"] <- 100
:假设第2个元素名称为"two",通过名称索引直接替换该位置元素值,当然也可以用整数索引来替换
向量运算
基础运算:
基础运算 | 作用 |
x+a,x-a,x*a,x/a | 对向量x每一个元素 + - * / a |
x+y,x-y,x*y,x/y | 对向量x和向量y每一对元素 + - * /(元素较少的向量会循环使用,但是需要他们之间的个数成整数倍关系) |
x**y | 幂运算 |
x%%y | 求余运算 |
x%/%y | 整除运算 |
x>y,x<y,x==y | 逻辑运算,逐一比对,返回逻辑值 |
%in% | 逻辑运算,逐一比对,返回逻辑值,左边的是否包含在右边里 |
数学函数:
数学函数 | 作用 |
abs(x) | 绝对值 |
sqrt(x) | 平方根 |
log(16, base = 2) | 对数,返回以2为底16的对数 |
log10(16) | 对数,返回以10为底16的对数 |
exp(x) | 指数 |
ceiling(x) | 向上取整 |
floor(x) | 向下取整 |
trunc(x) | 四舍五入取整 |
round(x, digits = 2) | 保留两位小数,不给定digits时默认四舍五入取整 |
signif(x, digits = 2) | 保留两位有效数字 |
sin(x),cos(x) | 三角函数 |
统计函数
统计函数 | 作用 |
sum(x) | 求和 |
prod(x) | 连乘 |
mean(x) | 均值 |
var(x) | 方差 |
sd(x) | 标准差 |
max(x),min(x) | 最大最小值 |
range(x) | 最大值和最小值 |
median(x) | 中位数 |
quantile(x, c(0.4, 0.8)) | 计算四分位数、八分位数,默认计算c(0, 0.25, 0.50, 0.75, 1) |
which.max(x) | 最大值的位置,其他统计值位置同理 |
矩阵 matrix
创建矩阵heat.map(state.x77)
:绘图,矩阵state.x77x <- 1:20
m <- matrix(x, nrow = 4, ncol = 5, byrow = T/F是否按行排列)
:由向量创建矩阵并赋值,默认按行排列dimnames(m) <- list(rnames, cnames)
:给矩阵m的行列命名dim(x) <- c(4, 5)
:给x的维度赋值,使得向量x转化为4*5矩阵
创建数组dim(x) <- c(2,2,5)
:给x的维度赋值,使得向量x转化为225的三维数组array(1:24, c(2,3,4), dimnames = list (dim1names, dim2names, dim3names))
:给数组命名,各参数分别是向量,维度赋值,各维度名字序列
矩阵的索引m[行, 列]
:访问矩阵m位于该行列的元素,行列可以是数值型、字符串型,也可以是向量m[-1, 2]
:访问除了第一行的第二列元素
矩阵的运算m+n
,m-n
:需要m,n行列数分别相同colSums(m)
,rowSums(m)
:列和,行和colMeans(m)
,rowMeans(m)
:列均值,行均值m*n
:矩阵内积,元素两两相乘,需要m,n行列数分别相同m %*% n
:矩阵外积diag(m)
:返回方阵的对角线元素t(m)
:转置
列表
向量只能存储一种数据类型,而列表的对象可以是任何数据结构,甚至列表本身list()
:生成列表mlist <- list(first = a, second = b, third = c)
:假设first, second, third是自定义的列名,a, b, c是自定义的变量。mlist是自定义的变量名mlist[1]
:访问第1个列表元素mlist[c(1,2)]
:访问第1~2列表元素mlist[c("first", "second")]
:通过名字访问这两个列表元素mlist$first
:访问列名为"first"的列表元素,输入mlist$就会自动弹出mlist含有的变量名
mlist[1]
:列表第1个元素,类型是列表mlist[[1]]
:列表第一个元素的内容,类型是向量class(x)
:返回x的数据类型
mlist[[5]] <- iris:给列表赋值,注意2个方括号喔,iris是R内置数据
mlist <- mlist[-5]
or mlist[[5]] <- NULL
:删除列表第5个元素
数据框
数据框是一种表格式的数据结构。数据框旨在模拟数据集,与其他统计软件例如SAS或者SPSS中的数据集的概念一致。
数据集通常是由数据构成的一个矩形数组,行表示观测,列表示变量。不同的行业对于数据集的行和列叫法不同。
数据框实际上是一个列表。列表中的元素是向量,这些向量构成数据框的列,每一列必须具有相同的长度,所以数据框是矩形结构,而且数据框的列必须命名。
创建数据框state <- data.frame(state.name, state.abb, state.region, state.x77)
:合成数据框,参数都是R内置数据向量
访问数据框 | 列表性质state[1]
:返回数据框的第1列,类型是列表state[c(2,4)]
:返回数据库的第2、4列state[, "state.abb"]
or state$state.abb
:利用名字可以直接取出对应行列的元素state[[1]]
:返回数据框的第1列,类型是向量
访问数据框 | attachattach(mtcars)
:用attach()加载数据框mtcar之后,直接输入行列名就可以返回相应元素了,甚至连$符都不用rownames(mtcars)
/ colnames(mtcars)
:查询行列名detach(mtcars)
:退出数据框mtcars
访问数据框 | withwith(mtcars, {hp})
:访问数据框mtcars的列名为hp的元素
因子 factor
变量分类:名义型,有序型,连续型
因子,在R中名义型变量和有序性变量称为因子。这些分类变量的可能值称为一个水平,例如有序型变量good, better, best,称为1个level。由这些水平值构成的向量就称为因子。
因子作用:分类,计算频数频率table(mtcars$cyl)
:频数统计,第1行为水平,第2行为频数f <- factor(c("red", "red", "blue"))
:创建因子week <- factor(c("Mon", "Mon", "Fri", "Thu"), ordered = T, levels = c("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"))
:创建因子cut(1:100, c(seq(0, 100, 10)))
:有规律的分组
缺失数据
NA:not available,代表缺失值,用来存储缺失信息
在函数中添加na.rm = TURE
表示跳过缺失值,注意这时候使用的数据数量已经减掉了NA个数mean(x, na.rm = TURE)
:跳过缺失值计算平均值is.na(x)
:识别缺失值,NA的位置返回TRUE,其他返回FALSEna.omit(x)
:x是向量,去掉数据集中的缺失值(多了一些属性信息)na.omit(sleep)
:sleep是数据集,去掉包含NA的行,但如果NA比较分散,那就删除掉太多数据了
is.nan(x)
:识别NaN,不可能值is.infinite(x)
:识别Inf,无穷值
字符串
正则表达式:
nchar("Hello World")
:返回向量中各个字符串的长度,空格也算字符length(month.name)
:返回向量中字符串的个数paste("Everybody", "loves", "stats")
:连接字符串,默认使用空格分隔paste("Everybody", "loves", "stats", sep = "-")
:连接字符串,自定义分隔符paste(names, "love stats")
:连接字符串,向量names中的元素分别连接substr(x = month.name, start = 1, stop = 3)
:提取字符串,提取出向量month.name中各元素前三个字符toupper(temp)
:把向量temp中的所有字符串转换为大写字母tolower(temp)
:把向量temp中的所有字符串转换为小写字母gsub("^(\\w)", "\\U\1", tolower(temp), perl = T)
:把向量temp中的所有字符串转换为小写字母,并设置首字母大写,U→L则得到首字母小写grep("A+", x, fixed = T)
:字符串匹配,在向量x中完全匹配A+,返回A+所在的位置,fixed用来控制是否使用正则表达式,很多字符串函数都有match("AC", x)
:字符串匹配,稍逊于grep()strsplit(path, "/")
:字符串分割,字符串path,分隔符/,返回一个列表outer(c(1:12), month.name, FUN = paste, sep = "-")
:字符串之间“笛卡尔积”,用paste表示方式为字符串连接,自定义分隔符
日期和时间
“ts”:time series时间序列,是一种数据类型,不是数据框的喔,包含Start、End、Frequency、Valuesa <- "2017-01-01"
:a是字符串as.Date(a)
:还是字符串as.Date(a, format = "%Y-%m-%d")
:类型转化为“Date”日期,format设置日期格式,参考strftime帮助文档seq(as.Date("2017-01-01"), as.Date("2017-07-05"), by = 5)
:以5天为间隔from 2017-01-01 to 2017-07-05的所有日期,自动认为是时间sales <- round(runif(48, min=50, max=100))
:生成随机数
ts(sales, start = c(2010,5), end = c(2014,4), frequency = 1):frequency = 1,4,12分别表示按年、季度、月份的含义生成数据格式
获取数据
三种获取数据的途径:
- 键盘输入数据;
- 读取存储在外部文件上的数据;(R不擅长预处理,所以预处理后再用R)
- 访问数据库系统来获取数据 。(RODBC包,提供通往各个数据库的接口)
【例】键盘输入数据
方法1:直接新建数据框
patientID <- c(1, 2, 3, 4)
admate <- 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")
data <- data.frame(patientID, admate, age, diabetes, status)
方法2:初始化数据框后用edit函数,进行可视化输入
data2 <- data.frame(patientID = character(0), admate = character(0),
age = numeric(), diabetes = character(), status = character(0))
data2 <- edit(data2) # 然后会弹出一个表格,直接填入数据就可以,编辑完后直接关闭表格编辑器就行
fix(data2) # 同上一行,也可以直接对data2进行修改,也是自动保存
读入文件
分隔符:空格 – .txt;逗号 – .csvhelp(package = "foreign")
:查看读取不同文件的read.函数
- 读入纯文本文件
x <- read.table("C:/user/input.txt")
head(x) # 截取文件前面几行数据
tail(x) # 截取文件后面几行数据
head(x, n=10) # 截取文件前面10行数据
- 读入csv文件
x <- read.table("input.csv", sep = ",")
x <- read.table("input.txt", header = TRUE)
:header表示是否把第一行当作变量名称x <- read.table("input.txt", header = TRUE, skip = 5)
:读取数据时跳过前面5行x <- read.table("input.txt", header = TRUE, skip = 50, nrow = 200)
:读取数据时跳过前面50行,且不超过前200行,即读取第51~200行
read.csv()
:默认分隔符为逗号",“来读取read.csv2()
:默认分隔符为分号”;“来读取read.delim()
:默认分隔符为制表符”\t"来读取read.fwf("fwf.txt", widths = c(2,3,4))
:生成控制宽度的文件,看起来更整齐,widths给出所占宽度值
- 读入网页文本文件
x <- read.table("网址", header = TRUE) # 其他参数都是一样的,就是把数据文件改成数据网址,R会把数据下载到本地
- 读入网页非文本文件(但这不是R擅长的)
install.packages("XML")
library(XML) # 包里面的readHTMLTable可以读取网页中表格
readHTMLTable("网址", which = 3) # 该网址的第三个表格
- 读入本地剪切板的内容
x <- read.table("clipboard", header = T, sep = "\t") # 方法1,clipboard剪切板
readClipboard() # 方法2,读取剪切板信息
- 读入压缩文件
read.table(gzfile("input.gz")) # .gz压缩文件
- 读入不标准格式的文件
readLine("input.csv" , n = 5)
:读入5行scan("scan.txt", what = list(numeric()))
:numeric指定类型,括号里默认为0,表示读到末尾scan("scan.txt", what = list(character(3), numeric(0), numeric(0)))
:括号里的3表示读该类型前三个
写入文件
- 写入纯文本文件
write()
系列函数write.table(x, file = "C:/Users/documents/newfile.txt")
write.table(x, file = "C:/Users/documents/newfile.csv", sep = ",")
:以逗号为分隔符,每个数据存放在单个单元格内;以空格为分隔符的话,内容则挤在一个单元格内。会把R中自动添上的行号也存进去,这时再read.table
一下,在R里就变成两列行号了。write.table(x, file = "C:/Users/documents/newfile.csv", sep = ",", row.name = FALSE)
:这样就不会把R自动添上的行号也写入文件了。
创建同名文件时用参数append
,表示是否加入已有文件,TRUE则加入到已有文件内容下方,FALSE则新建一个文件覆盖已有的同名文件。 - 写入压缩文件
write.table(mtcars, gzfile("newfile.txt.gz"))
:最好把文件扩展名都写上 - 其他
help(package = "foreign")
:查看foreign包里不同的读入写入格式
读写Excel文件
- 将.xlsx文件另存为.csv文件,然后直接用read函数读入就行(如果Excel文件包含宏就不行了)
read.table("mtcars.csv", header = T)
- 将文件内容复制到剪贴板,直接用读取剪贴板的形式读入
read.table("Clipboard", sep = "\t", header = T)
- 使用专门的包,XLConnect(载入时会自动先配置适合Java的环境)
vignette("XLConnect")
查看介绍
读入
library("XLConnet")
ex <- loadWorkbook("data.xlsx") # 参数为(文件名)
readWorksheet(ex, 1) # 参数分别为(对象, 第1个工作表sheet1)。读取后直接保存为一个数据框
readWorksheet(ex, 1, startRow = 0, startCol = 0, endRow = 50, endCol = 3, header = T) # 读取部分内容
readWorksheetFromFile("data.xlsx", 1) # 是loadWorkbook和readWorksheet的结合体,参数分别为(文件名,第1个工作表sheet1)
写入
方法一:
wb <- loadWorkbook("file.xlsx", create = T) # create = T表示创建一个新文件
createSheet(wb, "Sheet1") # 在对象文件中创建一个新工作表,命名为Sheet1
writeWorksheet(wb, data = mtcars, sheet = "Sheet1") # 写入数据mtcars到对象文件的相应工作表Sheet1中
saveWorkbook(wb) # 保存对象
方法二:
writeWorksheetToFile("file.xlsx", data = iris, sheet = "Sheet1") # 一步到位
- 使用专门的包,xlsx
library(xlsx)
x <- read.xlsx("data.xlsx", 1, startRow = 1, endRow = 100) # 读入"data.xlsx"的sheet1
write.xlsx(x, file = "rdata.xlsx", sheetName = "Sheet1", append = T) # 写入x到"rdata.xlsx"的"Sheet1",并设置为追加写入
读写R格式文件
优势:
- 对存储为内部文件格式的数据进行自动压缩处理
- 存储所有与待存储对象相关的R元数据(如果数据中包含因子、日期时间、类的属性等信),这些转换为其他文件就没有了
- RDS文件
saveRDS(iris, file = "iris.RDS")
:写入并存储,参数为(对象,文件名)readRDS("iris.RDS")
:读入 - RData文件
直接用工具栏打开load()
函数载入,如果文件中有和工作区变量重名的,会直接覆盖,这个要注意
所以载入RData文件之前最好对文件内容有所了解save(iris, iris3, file = "C:/Users/Desktop/iris.Rdata")
:写入,把两组数据都保存到一个文件中save.image()
:保存当前工作区所有对象,直接输这个命令即可
数据转换
is.data.frame(x)
:判断数据对象x是否为数据框dstate.x77 <- as.data.frame(state.x77)
:强制转换为数据框。如果对象中有字符串也有数字,那么数字也会强行转换为字符串格式methods(is)
methods(as)
:查看is函数/as函数包含的所有内容
Notes:并不是所有数据类型都可以互相强制转换,最方便的是向量,而向量可以转换为多种类型的数据。
例1:
x <- state.abb # 有50个数据
dim(x) <- c(5,10) # 将向量x定义在一个5*10二维空间
x <- state.abb
as.factor(x) # 将向量x变为因子类型
as.list(x) # 将向量x变为列表
例2:
state <- data.frame(x, state.region, state.x77) # 将向量x和其他两个构成一个数据框
state$Income # 取出数据框中一列,不适用于取行喔
state["Nevada", ] # 取出数据框中一行只能用这种一般的方式,别忘了逗号
例3:
y <- state["Nevada", ]
unname(y) # 去除列名
unlist(y) # 转换成向量
例4:数据太多,取子集
who <- read.csv("WHO.csv",header = T)
whol <- who[c(1:50),c(1:10)]
View(who1) # 用新标签页查看表格,更直观
who3 <- who[which(who$Continent = 7)] # 筛选出Continent项为7的行查看
who4 <- who[which(who$CountryID>50 & who$CountryID<=100)] # 筛选出CountryID项为介于50~100的行查看
who4 <- subset(who, who$CountryID>50 & who$CountryID<=100) # 使用subset筛选更方便
x <- 1:100
sample(x, 30) # 使用sample函数进行随机抽样
sample(x, 60, replace = T) # 使用sample函数进行随机有放回抽样
sort(sample(x, 60, replace = T)) # 在sample结果的基础上排序
mtcars[-1:-5,] # 删除1~5列
例5:合并数据
data.frame(USArrests,state.division) # 在数据框USArrests加一列state.division
cbind(USArrests,state.division) # 合并列
data1 <- head(USArrests,20)
data2 <- tail(USArrests,20)
rbind(data1,data2) # 合并行,但要求要有相同的列数、列名才可以合并,重复行会保留而不删除
duplicated(data4) # 返回是否为重复数据
data4[duplicated(data4), ] # 取出重复的部分,只取其一
data4[!duplicated(data4), ] # 取出非重复的部分
unique(data4) # 直接把重复的数据去除,只取其一
例6:转置数据框 t(…)
t(mtcars) # 转置矩阵
rev(letters) # 翻转向量
rownames(women) # 提取行名,这里是1~15序号
rev(rowname(women)) # 翻转提取的行名
women[rev(rowname(women)), ] # 按照翻转提取的行名进行索引,得到数据框women上下翻转了
例7:修改数据框中的值
women$height*2.54 # 把height列各数据乘2.54
data.frame(women$height*2.54, women$weight) # 重新组合数据框,可行但低效
transform(women, height=height*2.54) # 使用函数transform直接修改,若用已有列名的话会覆盖原数据
transform(women, cm=height*2.54) # 直接在原有数据基础上新增一列cm列
例8:数据框排序
sort(rivers) # 数字默认从小到大顺序排序
sort(state.name) # 单词默认从首字母依次排序
rev(sort(rivers)) # 加上rev函数按相反方向排序
### sort函数只能对向量排序,不能对数据框进行排序,但是可以变通一下
mtcars[sort(rownames(mtcars)), ] # 将数据框mtcars按列名排序
order(rivers) # 返回对应值从小到大排序后在第几位
mtcars[order(mtcars$mpg), ] # 将数据框mtcars按mpg列数值从小到大排序
mtcars[order(-mtcars$mpg), ] # 将数据框mtcars按mpg列数值从大到小排序(加负号后全部变成负数,从小到大排序之后输出,但输出的是相应位置的原始数据,所以就变成从大到小排序了)
mtcars[order(mtcars$mpg,mtcars$disp), ] # 在mpg列数值相同的情况下,按disp列数值从小到大排序
?rank
例9:对行或列进行运算
worldPhones <- as.data.frame(worldPhone) # 转换为数据框
rs <- rowSums(worldPhones) # 按行求和
cm <- colMeans(worldPhones) # 按列求平均
total <- cbind(worldPhones,Total = rs) # 将各行总和添加到最后一列,列名为Total
rbind(total,Mean = cm) # 将各列平均值添加到最后一行,行名为Mean
apply(worldPhones,MARGIN=1,FUN=sum) # 按行求和
apply(worldPhones,MARGIN=2,FUN=mean) # 按列求平均
### apply适用于数据框或矩阵
lapply(state.center,FUN=length) # 适用于列表,计算列表的长度,返回列表
sapply(state.center,FUN=length) # 计算列表的长度,返回向量
tapply(state.name,division,FUN=length) # 统计state.name下各数据的division个数,返回向量
数据中心化,是指数据集中的各项数据减去数据集的均值。x-mean(x)
数据标准化,是指在中心化之后在除以数据集的标准差,即数据集中的各项数据减去数据集的均值再除以数据集的标准差。(x-mean(x))/sd(x)
scale(state, center = T, scale = T) # center--是否中心化,scale--是否标准化
数据转换 - reshape2包
如果不用reshape2包解决“按照某项合并”的问题:
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)
merge(x,y,by="k1") # 根据k1进行合并
merge(x,y,by="k2",incomparables = NA) # 根据k2进行合并,并丢掉k2项为NA的情况
merge(x,y,by=c("k1","k2")) # 根据k1和k2进行合并
准备reshape2包:
install.packages("reshape2") # 安装
library(reshape2) # 载入
help(package = "reshape2")
melt
:对宽数据进行处理,得到长数据 – 类似于数据透视表的原表
names(airquality) <- tolower(names(airquality)) # 为方便演示,将列名改成小写
aql <- melt(airquality) # 依次列出列名与值,按列读取
aql <- melt(airquality, id.vars = c("month","day")) # 按时间顺序依次列出列名与值,按列读取
cast
:对长数据进行处理,得到宽数据 – 类似于数据透视表
aqw <- dcast(aql,month +day ~variable)
数据转换 - tidyr包
准备tidyr包:
install.packages(c("tidyr")) # tidy干净整洁
library(tidyr)
例1:列的扩宽与恢复
tdata <- mtcars[1:10,1:3]
tdata <- data.frame(names = rownames(tdata),tdata)
gdata <- gather(tdata, key = "Key", value = "Value", cyl, disp, mpg) # 列转换
gdata <- gather(tdata, key = "Key", value = "Value", 2:4) # 列转换,和上式结果一样
spread(gdata, key = "Key", value = "Value") # 列转换,回到了tdata的格式
# key:设置需要扩宽的类别变量;value:设置需要扩宽的变量的度量值
例2:列的拆分与连接
df <- data.frame(x=c(NA,"a.b","a.d","b.c"))
x <- separate(df,col=x,into=c("A","B")) # 拆分,默认以.为分隔符
df <- data.frame(x=c(NA,"a.b-b","a-d","b-c"))
x <- separate(df,col=x,into=c("A","B"),sep="-") # 拆分,设置以连字符-为分隔符
unite(x,col="AB",A,B,sep="-") # 连接,设置以连字符-为分隔符
数据转换 - dplyr包
非常强大,前面很多数据转换的操作都能实现
准备dplyr包:
install.packages(c("dplyr"))
library(dplyr)
dplyr::filter(iris,Sepal.Length>7)
:过滤掉小于等于7的dplyr::distinct(rbind(iris[1:10,],iris[1:15,]))
:去除重复的dplyr::slice(iris,10:15)
:切片,取出数据任意行dplyr::sample_n(iris,10)
:随机取样,随机抽10行dplyr::sample_frac(iris,0.1)
:按0.1比例随机取样dplyr::arrange(iris,Sepal.Length)
:排序,按Sepal.Length从小到大排序dplyr::arrange(iris,desc(Sepal.Length))
:排序,按Sepal.Length从大到小排序,descend降序select()
:查找,比如:含有某些固定字符、只知道开头结尾的字符…summarise(iris,avg=mean(Spal.Length))
:统计函数dplyr::group_by(iris,Spacies)
:分组,根据Spacies这一列给iris分组iris %>% group_by(Spacies)
:使用管道符%>%,效果同上iris %>% group_by(Spacies) %>% summaries(avg=mean(Sepal.Width))
:对iris分组后统计iris %>% group_by(Spacies) %>% summaries(avg=mean(Sepal.Width)) %>% arrange(avg)
:统计后排序dplyr::mutate(iris,new=Sepal.Length+Petal.Length)
:加入新列
例1:列连接
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") # 左连接
dplyr::right_join(a,b,by="x1") # 右连接
dplyr::full_join(a,b,by="x1") # 全连接,取并集
dplyr::semi_join(a,b,by="x1") # 内连接,取交集
dplyr::anti_join(a,b,by="x1") # 取交集的补集
first <- slice(mtcars, 1:20) # 取出前二十行,但不包含行名
mtcars <- mutate(mtcars, Model=rownames(mtcars)) # 先添加一列
first <- slice(mtcars, 1:20) # 取出前二十行
second <- slice(mtcars, 10:30) # 取出前二十行
intersect(first,second)
:取交集dplyr::union_all(first,second)
:取并集dplyr::union(first,second)
:取非冗余的并集setdiff(first,second)
:取second在first的补集,即first中去除second后剩下的setdiff(second,first)
:取first在second的补集