高级数据管理
数值和字符处理函数
数学函数
abs(x):求绝对值,例如 abs(-4) #返回值为4
sqrt(x):求平方根,例如 sqrt(25) #返回值为5
ceiling(x):不小于x 的最小整数,例如 ceiling(3.475) #返回值为4
floor(x):不大于x 的最大整数,例如 floor(3.475) #返回值为3
trunc(x):向0的方向截取的x 中的整数部分,例如 trunc(5.99) #返回值为5
round(x, digits=n):将x舍入为指定位的小数,例如 round(3.475, digits=2) #返回值为3.48
signif(x, digits=n):将x舍入为指定的有效数字位数,例如 signif(3.475, digits=2) #返回值为3.5
cos(x)、sin(x)、tan(x):余弦、正弦和正切,例如 cos(2) #返回值为–0.416
acos(x)、asin(x)、atan(x):反余弦、反正弦和反正切,例如 acos(-0.416) #返回值为2
cosh(x)、sinh(x)、tanh(x):双曲余弦、双曲正弦和双曲正切, 例如 sinh(2) #返回值为3.627
acosh(x)、asinh(x)、atanh(x):反双曲余弦、反双曲正弦和反双曲正切,例如 asinh(3.627) #返回值为2
log(x, base=n):对x取以n 为底的对数
log(x):自然对数
log10(x):以10为底的对数
exp(x):指数函数,例如exp(2.3026) #返回值为10
统计函数
mean(x):平均数,例如 mean(c(1,2,3,4)) #返回值为2.5
median(x):中位数,例如 median(c(1,2,3,4)) #返回值为2.5
sd(x):标准差,例如 sd(c(1,2,3,4))
var(x):方差,例如 var(c(1,2,3,4))
mad(x):绝对中位差,例如 mad(c(1,2,3,4)) #返回值为1.48
quantile(x, probs):求分位数,例如 y <- quantile(x,c(.3,.84)) #返回值为x的30%和84%分位点
range(x):求值域,例如 range(c(1,2,3,4)) #返回值为c(1,4)
sum(x):求和,例如 sum(c(1,2,3,4)) #返回值为10
diff(x, lag=n):差分函数,lag为差分项,默认值为1,例如 diff(c(1, 5, 23, 29)) #返回值为c(4,18,6)
min(x):求最小值,例如 min(c(1,2,3,4)) #返回值为1
max(x):求最大值,例如 max(c(1,2,3,4)) #返回值为4
scale(x, center=TRUE, scale=TRUE):为数据对象x按列进行中心化(center=TRUE)或标准化(center=TRUE, scale=TRUE)
概率函数
在R中,概率函数形如 :[dpqr]分布名称缩写( )
其中第一个字母表示其所指分布的某一方面:
d = 密度函数(density function)
p = 分布函数(distribution function)
q = 分位数函数(quantile function)
r = 生成随机数(随机偏差)
# 在[-3, 3]区间上绘制标准正态曲线
x <- pretty(c(-3,3), 30) # 在[-3, 3]选取31个等分点
y <- dnorm(x)
plot(x, y, type = "l", xlab = "Normal Deviate", ylab = "Density", yaxs = "i" )
pnorm(1.96) #位于z=1.96 左侧的标准正态曲线下方面积,返回值为0.975
qnorm(.9, mean=500, sd=100) #均值为500,标准差为100的正态分布的0.9分位点,返回值为628.16
rnorm(50, mean=50, sd=10) #生成50 个均值为50,标准差为10的正态随机数
设定随机数种子
在每次生成伪随机数的时候,函数都会使用一个不同的种子,因此也会产生不同的结果;可以通过函数 set.seed() 显式指定这个种子,让结果可以重现
runif(5)
# 输出
0.5684550 0.2155904 0.6656250 0.6798496 0.7349901
runif(5)
# 输出
0.70508234 0.45849879 0.21018669 0.08474743 0.79296225
set.seed(1234)
runif(5)
# 输出
0.1137034 0.6222994 0.6092747 0.6233794 0.8609154
set.seed(1234)
runif(5)
# 输出
0.1137034 0.6222994 0.6092747 0.6233794 0.8609154
生成多元正态数据
MASS包中的mvrnorm()函数可以生成给定均值向量和协方差阵的多元正态分布的随机数:
mvrnorm(n, mean, sigma)
其中n是样本大小,mean为均值向量,而sigma是协方差矩阵
library(MASS)
options(digits=3)
set.seed(1234) # 设定随机数种子
mean <- c(230.7, 146.7, 3.6)
sigma <- matrix( c(15360.8, 6721.2, -47.1,
6721.2, 4700.9, -16.5,
-47.1, -16.5, 0.3), nrow=3, ncol=3)
mydata <- mvrnorm(500, mean, sigma) # 取500个观测值
mydata <- as.data.frame(mydata) # 把矩阵转换为数据框
names(mydata) <- c("y", "x1", "x2") # 指定数据框的名称
dim(mydata) # 查看数据
# 输出
500 3
head(mydata, n=10) # 查看前10行数据
# 输出
y x1 x2
1 98.8 41.3 3.43
2 244.5 205.2 3.80
3 375.7 186.7 2.51
4 -59.2 11.2 4.71
5 313.0 111.0 3.45
6 288.8 185.1 2.72
7 134.8 165.0 4.39
8 171.7 97.4 3.64
9 167.2 101.0 3.50
10 121.1 94.5 4.10
字符处理函数
nchar(x):计算x 中的字符数量,例如x <- c("ab", "cde","fghij"),则nchar(x[3])返回值为5
substr(x, start, stop):提取子串,例如 x <- "abcdef",则 substr(x, 2, 4)返回值为"bcd"
grep(pattern, x, ignore.case=FALSE, fixed=FALSE):在x中匹配搜索pattern,返回值为匹配的下标;若fixed=FALSE,则pattern 为一个正则表达式,若fixed=TRUE,则pattern 为一 个文本字符串。例如grep("A", c("b", "A", "c"), fixed=TRUE) # 返回值为2
sub(pattern, replacement, x, ignore.case=FALSE,fixed=FALSE):在x中搜索pattern,并以文本replacement将其替换。例如sub("\\s", ".", "Hello There") # 返回值为Hello.There
注意,"\s"是一个用来查找空白的正则表达式
strsplit(x, split, fixed=FALSE):在split处分割字符向量x中的元素,例如y <- strsplit("abc", "") # 返回含有3个元素的列表,包含的内容为"a" "b" "c"
paste(…, sep=""):连接字符串,分隔符为sep,例如paste("x", 1:3, sep="M") # 返回值为c("xM1","xM2" "xM3")
toupper(x):大写转换,例如 > toupper("abc") # 返回值为 "ABC"
tolower (x):小写转换,例如 > tolower ("ABC") # 返回值为 "abc"
其他实用函数
length(x):对象x的长度,例如x <- c(2, 5, 6, 9) # 返回值为4
seq(from, to, by):生成一个序列,例如indices <-seq(1,10,2) # indices的值为c(1, 3, 5, 7, 9)
rep(x, n):将x重复n次,例如y <- rep(1:3, 2) # y 的值为c(1, 2, 3, 1, 2, 3)
cut(x, n):将连续型变量x分割为有着n个水平的因子
pretty(x, n):创建美观的分割点,绘图中常用。通过选取n+1个等间距的取整值,将一个连续型变量x分割为n个区间
cat(... , file =“myfile”, append =FALSE):连接...中的对象
转义字符:\n表示新行,\t为制表符,\’为单引号,\b为退 格 … …
name <- "Bob"
cat( "Hello", name, "\b.\n", "Isn\'t R", "\t", "GREAT?\n")
# 输出
Hello Bob.
Isn't R GREAT?
例题: 将学生的各科考试成绩组合为单一的成绩衡量指标,基于相对名次(前20%、后20%等)给出
从A到F的评分,根据学生姓氏和名字的首字母对花名册进行排序
# 第1步:创建学生花名册数据框roster
options(digits=2)
Student <- c("John Davis", "Angela Williams", "Bullwinkle Moose", "David Jones", "Janice Markhammer", "Cheryl Cushing","Reuven Ytzrhak", "Greg Knox", "Joel England","Mary Rayburn")
Math <- c(502, 600, 412, 358, 495, 512, 410, 625, 573, 522)
Science <- c(95, 99, 80, 82, 75, 85, 80, 95, 89, 86)
English <- c(25, 22, 18, 15, 20, 28, 15, 30, 27, 18)
roster <- data.frame(Student, Math, Science, English, stringsAsFactors=FALSE) # 限制字符向量变成因子
# 第2步:对各科成绩进行标准化操作(因为数学、科学和英语考试 的分值不同,所以需要在组合之前让它们变得可以比较)
z <- scale(roster[ , 2:4])
# 第3步:创建向量score,来计算每个学生3科成绩的平均值,并将score合并到花名册数据框roster 中
score <- apply(z, 1, mean)
roster <- cbind(roster, score)
# 第4步:为了给出五级制学分评级,对score变量计算中位数
y <- quantile(score, c(.8,.6,.4,.2))
# 第5步:新建变量grade,计算学生的五级制评分
roster$grade[score >= y[1]] <- "A"
roster$grade[score < y[1] & score >= y[2]] <- "B"
roster$grade[score < y[2] & score >= y[3]] <- "C"
roster$grade[score < y[3] & score >= y[4]] <- "D"
roster$grade[score < y[4]] <- "F"
# 第6步:将学生姓名拆分为姓氏和名字
name <- strsplit((roster$Student), " ") # 以空格为界对学生的姓名进行拆分,返回拆分后的姓名列表
# 第7步:新建变量Firstname和Lastname存放名字和姓氏,并合并 到roster中
lastname <- sapply (name, "[", 2) # [”可以提取对象的一 部分,sapply专门对列表或者数据框进行分组统计
firstname <- sapply (name, "[", 1)
roster <- cbind (firstname, lastname, roster[,-1]) # 删除roster的第一列姓名列
# 第8步:依姓氏和名字对花名册roster进行排序
roster <- roster[order(lastname,firstname), ]
roster
# 输出
firstname lastname Math Science English score grade
3 Bullwinkle 412 80 18 -0.86 D
6 Cheryl 512 85 28 0.35 C
10 Mary 522 86 18 -0.18 C
1 John Davis 502 95 25 0.56 B
9 Joel England 573 89 27 0.70 B
4 David Jones 358 82 15 -1.16 F
8 Greg Knox 625 95 30 1.34 A
5 Janice Markhammer 495 75 20 -0.63 D
2 Angela Williams 600 99 22 0.92 A
7 Reuven Ytzrhak 410 80 15 -1.05 F
控制流
重复和循环
for结构
for (var in seq) statement
for (i in 1:10) print("Hello") # Hello被输出了10次
while循环
while (cond) statement
i <- 10
while (i>0) {
print("hello")
i <- i -1
}
条件语句
if-else结构
if (cond) statement
if (cond) statement1 else statement2
若cond为TRUE,则执行statement语句
if (is.character(grade)) grade <- as.factor(grade)
# 如果grade是一个字符向量,它就会被转换为一个因子
if ( !is.factor(grade)) grade <- as.factor(grade)
else print("Grade already”)
# 如果grade不是一个因子,它就会被转换为一个因子;如果它是一个因子,就会输出一段信息
ifelse结构
ifelse (cond, statement1, statement2)
若cond为TRUE,则执行statement1语句;若cond为FALSE,则 执行statement2语句
ifelse (score > 0.5, print("Passed"), print("Failed"))
outcome <- ifelse (score > 0.5, "Passed", "Failed")
switch结构
switch (expr, …)
其中“…” 表示与expr的各种可能输出值绑定的语句
feelings <- c("sad", "afraid")
for (i in feelings)
print(switch(i,
happy = "I am glad you are happy",
afraid = "There is nothing to fear",
sad = "Cheer up",
angry = "Calm down now" )
)
# 输出
[1] "Cheer up"
[1] "There is nothing to fear"
用户自编函数
myfunction <- function(arg1, arg2, ... ){
statements return(object)
}
注意:
函数中的对象只在函数内部使用
返回对象的数据类型是任意的,从标量到列表都可以
例题: 编写一个函数,用来计算数据对象的集中趋势和散布情况:
可以选择性地计算参数统计量(均值和标准差)和非参数统计量(中位数和绝对中位差);
结果以列表的形式给出;
可以选择是否自动输出结果;
除非另外指定,否则此函数的默认行为是计算参数统计量并且不输出结果。
mystats <- function(x, parametric=TRUE, print=FALSE) {
if (parametric) { # 根据参数parametric确定应该怎样计算
center <- mean(x); spread <- sd(x)
}
else {
center <- median(x); spread <- mad(x)
}
if (print & parametric) { # 根据参数print确定是否打印
cat("Mean=", center, "\n", "SD=", spread, "\n")
}
else if (print & !parametric) {
cat("Median=", center, "\n", "MAD=", spread, "\n")
}
result <- list(center=center, spread=spread)
return(result)
}
set.seed(1234)
x <- rnorm(500)
y <- mystats(x) # y$center包含均值,y$spread包含标准差,并且没有输出结果
y <- mystats(x, parametric=FALSE, print=TRUE)
# 输出
Median= -0.021
MAD= 1
例题: 编写一个函数,可让用户选择输出当天日期的格式:
mydate <- function(type="long") {
switch(type,
long = format( Sys.time( ), "%A %B %d %Y" ),
short = format( Sys.time( ), "%m-%d-%y" ),
cat(type, "is not a recognized type\n")) # 函数cat()仅会在输入的日期 格式类型不匹配"long"或"short"时执行
}
mydate("long")
# 输出
[1] "星期六 八月 10 2019"
mydate("short")
# 输出
[1] "08-10-19"
mydate()
# 输出
[1] "星期六 八月 10 2019"
mydate("medium")
# 输出
medium is not a recognized type
数据的整合与重塑
转置
函数t( ) 可对一个矩阵或数据框进行转置
mtcars<-mtcars
cars <- mtcars[1:5, 1:4]
# 输出
cars
mpg cyl disp hp
Mazda RX4 21 6 160 110
Mazda RX4 Wag 21 6 160 110
Datsun 710 23 4 108 93
Hornet 4 Drive 21 6 258 110
Hornet Sportabout 19 8 360 175
t(cars)
# 输出
Mazda RX4 Mazda RX4 Wag Datsun 710 Hornet 4 Drive Hornet Sportabout
mpg 21 21 23 21 19
cyl 6 6 4 6 8
disp 160 160 108 258 360
hp 110 110 93 110 175
整合数据
aggregate(x, by, FUN)
其中,x是待折叠的数据对象,by是由整合变量所组成的列表,FUN是计算新观测的标量函数
options(digits=3)
attach(mtcars)
aggdata <-aggregate(mtcars, by=list(cyl,gear),
FUN=mean,
na.rm=TRUE) # 根据气缸数cyl和档位数gear整合mtcars数据,并返回各数值型变量的均值
aggdata
# 输出
Group.1 Group.2 mpg cyl disp hp drat wt qsec vs am gear carb
1 4 3 21.5 4 120 97 3.70 2.46 20.0 1.0 0.00 3 1.00
2 6 3 19.8 6 242 108 2.92 3.34 19.8 1.0 0.00 3 1.00
3 8 3 15.1 8 358 194 3.12 4.10 17.1 0.0 0.00 3 3.08
4 4 4 26.9 4 103 76 4.11 2.38 19.6 1.0 0.75 4 1.50
5 6 4 19.8 6 164 116 3.91 3.09 17.7 0.5 0.50 4 4.00
6 4 5 28.2 4 108 102 4.10 1.83 16.8 0.5 1.00 5 2.00
7 6 5 19.7 6 145 175 3.62 2.77 15.5 0.0 1.00 5 6.00
8 8 5 15.4 8 326 300 3.88 3.37 14.6 0.0 1.00 5 6.00
detach(mtcars)