中级绘图

1、散点图

1
2
3
4
5
6
7
#散点图
attach(mtcars)
plot(wt,mpg,main="基本散点图:英里数与车重",xlab = "车重(lbs/1000)",ylab="一加仑的公里数",pch=19)
#添加一条拟合的直线
abline(lm(mpg~wt),col="red",lwd=2,lty=1)
#添加一条拟合的平滑曲线
lines(lowess(wt,mpg),col="blue",lwd=2,lty=2)

1
2
library(car)
scatterplot(mpg~wt|cyl,data=mtcars,lwd=2,main="不同气缸英里数与车重",xlab="车重(lbs/1000)",ylab="每加仑距离",legend.plot=TRUE,id.method="identify",labels=row.names(mtcars),boxplots="xy")

1.1、散点矩阵图

1
2
3
4
#散点图矩阵
plot(~mpg+disp+drat+wt,data=mtcars)
#upper.panel = NULL只展现下三角,图形是对称的
pairs(~mpg+disp+drat+wt,data=mtcars,upper.panel = NULL)


1
2
3
4
#car包中的函数
library(car)
#主对角线添加了核密度曲线和轴须图
scatterplotMatrix(~mpg+disp+drat+wt,data=mtcars,spread=FALSE,lty.smooth=2,main="散点矩阵图")


1
2
#根据某变量进行分组展现by.groups = TRUE根据各个子集生成拟合图
scatterplotMatrix(~mpg+disp+drat+wt|cyl,data=mtcars,by.groups = TRUE,diagonal="histogram",main="散点矩阵图")

1
2
3
4
5
6
7
8
9
10
library(gclus)
mydata<-mtcars[c(1,3,5,6)]
#获取相关系数的绝对值矩阵
mydata.corr<-abs(cor(mydata))
#根据相关系数获取颜色矩阵
mycolors<-dmat.color(mydata.corr)
#根据相关系数重排变量
myorder<-order.single(mydata.corr)
cpairs(mydata,myorder,panel.colors = mycolors,gap=.5,main="根据相关性排序与着色图")

1.2、高密度散点图

1
2
3
4
5
6
7
8
9
set.seed(1234)
n<-10000
c1<-matrix(rnorm(n,mean = 0,sd=0.5),ncol=2)
c2<-matrix(rnorm(n,mean = 3,sd=2),ncol=2)
mydata<-rbind(c1,c2)
mydata<-as.data.frame(mydata)
names(mydata)<-c("x","y")
with(mydata,plot(x,y,pch=19,main="Scatter Plot with 10000 points"))

1
with(mydata,smoothScatter(x,y,main="Scatter Plot with 10000 points"))

1
2
3
4
5
library(hexbin)
with(mydata,{
bin<-hexbin(x,y,xbins=50)
plot(bin,main="六边形散点图")
})

1
2
library(IDPmisc)
with(mydata,iplot(x,y,main="颜色散点图"))

1.3、三维散点图

1
2
3
library(scatterplot3d)
attach(mtcars)
scatterplot3d(wt,disp,mpg,main="三维散点图")

1
2
#增加垂线
scatterplot3d(wt,disp,mpg,pch=16,highlight.3d=TRUE,type="h",main="三维散点图")

1
2
3
4
#增加回归面
s3d<-scatterplot3d(wt,disp,mpg,pch=16,highlight.3d=TRUE,type="h",main="三维散点图与回归面")
fit<-lm(mpg~wt+disp)
s3d$plane3d(fit)

1
2
3
4
#交互式可旋转三维图形
library(rgl)
attach(mtcars)
plot3d(wt,disp,mpg,col="red",size=5)

1
2
3
#另一种交互图,更好
library(Rcmdr)
scatter3d(wt,disp,mpg)

1.4、气泡图

1
2
3
4
5
##气泡图
r<-sqrt(disp/pi)
symbols(wt,mpg,circle=r,inches = 0.30,fg="white",bg="lightblue",main="气泡图,比例为排量",
ylab="每加仑公里数",xlab="自重(lbs/1000)")
text(wt,mpg,rownames(mtcars),cex=0.6)

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
28
#转换为数值型
Orange$Tree<-as.numeric(Orange$Tree)
ntrees<-max(Orange$Tree)
xrange<-range(Orange$age)
yrange<-range(Orange$circumference)
plot(xrange,yrange,type="n",
xlab="树龄/天",ylab="直径/mm")
colors<-rainbow(ntrees)
linetype<-c(1:ntrees)
plotchar<-seq(18,18+ntrees,1)
for(i in 1:ntrees){
tree<-subset(Orange,Tree==i)
lines(tree$age,tree$circumference,
type="b",lwd=2,
lty=linetype[i],
col=colors[i],
pch=plotchar[i])
}
title("树图","折线示例")
legend(xrange[1],yrange[2],
1:ntrees,cex=0.8,col=colors,pch=plotchar,lty=linetype,title="Tree")

3、相关图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
##相关图
library(corrgram)
#order = TRUE矩阵行列均使用主成分分析进行了重新排序
#lower.panel与upper.panel设置下与上对角线元素类型
#panel.pie 用饼图的填充比例来表示相关性大小
#panel.shade 用阴影的深度来表示相关性
#panel.ellipse 绘制置信椭圆和平滑拟合曲线
#panel.pts 绘制散点图
#text.panel与diag.panel控制主对角线元素类型
#panel.minmax 输出变量的最大最小值
#panel.txt 输出的变量名字
corrgram(mtcars,order=TRUE,lower.panel = panel.shade,upper.panel = panel.pie,text.panel = panel.txt,
main="相关系数图")

1
2
3
4
5
6
corrgram(mtcars,order=TRUE,
lower.panel = panel.ellipse,
upper.panel = panel.pts,
text.panel = panel.txt,
diag.panel = panel.minmax,
main="相关系数图")

4、马赛克图

1
2
3
4
5
6
7
8
9
#马赛克图
library(vcd)
ftable(Titanic)
#马赛克图隐含着大量的数据信息。例如:
#(1)从船员到头等舱,存活率陡然提高;
#(2)大部分孩子都处在三等舱和二等舱中;
#(3)在头等舱中的大部分女性都存活了下来,而三等舱中仅有一半女性存活;
#(4)船员中女性很少,导致该组的Survived标签重叠(图底部的No和Yes)。
mosaic(Titanic,shade = TRUE,legend=TRUE)

功效分析

  • 在给定置信度的情况下,判断检测到给定效应值时所需的样本量。反过来,它也可以帮助你在给定置信度水平情况下,计算在某样本量内能检测到给定效应值的概率。

1、假设检验速览

  • 样本大小: 实验设计中每种条件/组中观测的数目
  • 显著性水平: I型错误的概率来定义。也可以把它看做是发现效应不发生的概率
  • 功效: 通过1减去II型错误的概率来定义。可以把它看做是真实效应发生的概率。
  • 效应值: 指的是在备择或研究假设下效应的量。效应值的表达式依赖于假设检验中使用的统计方法

功效分析就是给定三个值得情况下,求得另外一个值

2、用 pwr 包做功效分析

2.1、t检验

1
2
3
4
5
6
7
pwr.t.test(n=,d=,sig.level=,power=,alternative=)
#n: 样本大小
#d: 效应值,d=(u1-u2)/o, u1与u2为两组均值,o为标准差
#sig.level: 显著水平
#power: 功效水平
#type: 检验类型,双样本t检验(two.sample)、单样本t检验(one.sample)或相依样本t检验(paired)。默认为双样本t检验。
#alternative: 指统计检验是双侧检验(two.sided)还是单侧检验(less或greater)。默认为双侧检验
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
> ##t检验
> library(pwr)
>
> #实例1、手机与驾驶反应时间实验,根据过去经验知道反应时间的标准差为1.25s,当前认为相差1s表示巨大差异,此时可
> #设定d=1/1.25=0.8或更大,如果差异存在,你希望90%把握检测到,由于随机变异性存在,希望95%把握不会误报差异显著
> pwr.t.test(d=0.8,sig.level = 0.05,power = 0.9,type = "two.sample",alternative = "two.side")
Two-sample t test power calculation
n = 33.82554
d = 0.8
sig.level = 0.05
power = 0.9
alternative = two.sided
NOTE: n is number in *each* group
>
> #结果显示需要每组34个受试者,一共2组68人
>
> #实例2、如果在比较实例1的2种情况时候,想检测到总体均值0.5个标准差的差异,将误报的几率限制在%1,只有40个受试者,
> #那么能检测到这种差异的概率是多大?
> pwr.t.test(n=20,d=0.5,sig.level = 0.01,type = "two.sample",alternative = "two.side")
Two-sample t test power calculation
n = 20
d = 0.5
sig.level = 0.01
power = 0.1439551
alternative = two.sided
NOTE: n is number in *each* group
>
> #结果表明只有14%的把握能检测到这种差异,即差值为0.5*1.25=0.625s,86%的可能性会错过,此时考虑是否应该进行该测试
>
> #如果两组的样本大小不同,使用:
> pwr.t2n.test(n1=20,n2=30,d=0.5,sig.level = 0.01,alternative = "two.side")
t test power calculation
n1 = 20
n2 = 30
d = 0.5
sig.level = 0.01
power = 0.183246
alternative = two.sided

2.2、方差分析

效应值f计算公式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> ##方差分析
> #pwr.anova.test(k=组数,n=各组样本大小,f=效应值,sig.level=显著水平,power=功效)
> pwr.anova.test(k=5,f=0.25,sig.level=0.05,power=0.8)
Balanced one-way analysis of variance power calculation
k = 5
n = 39.1534
f = 0.25
sig.level = 0.05
power = 0.8
NOTE: n is number in each group
> #此方法需要估计同方差时5个组的均值

2.3、相关性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> ##相关性
> #pwr.r.test(n=观测数,r=效应值(线性相关系数),sig.level = 显著水平,power = 功效,alternative =c("two.sided", "less","greater"))
> #抑郁与孤独的关系,设定相关系数为0.25,大于0.25表示有关系拒绝零假设,显著水平为0.05,90%的信心拒绝零假设,
> pwr.r.test(r=0.25,sig.level = 0.05,power = 0.9,alternative ="greater")
approximate correlation power calculation (arctangh transformation)
n = 133.2803
r = 0.25
sig.level = 0.05
power = 0.9
alternative = greater
> #需要134个受试者

2.4、线性模型

效应值f2计算公式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
> ##线性模型
> #pwr.f2.test(u=分子自由度,v=分母自由度,f2=效应值,sig.level = ,power = )
> #当要评价一组预测变量对结果的影响程度时,适宜用第一个公式来计算f2;当要评价一组预
> #测变量对结果的影响超过第二组变量(协变量)多少时,适宜用第二个公式。
> #现假设你想研究老板的领导风格对员工满意度的影响,是否超过薪水和工作小费对员工满意度的影响。
> #领导风格可用四个变量来评估,薪水和小费与三个变量有关。过去的经验表明,薪水
> #和小费能够解释约30%的员工满意度的方差。而从现实出发,领导风格至少能解释35%的方差。
> #假定显著性水平为0.05,那么在90%的置信度情况下,你需要多少受试者才能得到这样的方差贡
> #献率呢?
>
> #此时u=3(总预测变量-集合B预测变量),f2=(0.35-0.3)/(1-0.35)=0.0769
> pwr.f2.test(u=3,f2=0.0769,sig.level =0.05 ,power = 0.9)
Multiple regression power calculation
u = 3
v = 184.2426
f2 = 0.0769
sig.level = 0.05
power = 0.9
>
> #多元回归中,分母的自由度等于N- k- 1, N是总观测数, k是预测变量数。本例中, N-7-1= 185,即需要样本大小N = 185 + 7 + 1 = 193

2.5、比例检验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
> ##比例检验
> #pwr.2p.test(h=效应值,n=各组相同的样本量,sig.level = ,power = )
> #当n不同时候,使用
> #pwr.2p.test(h=效应值,n1=,n2=,sig.level = ,power = )
> #h使用ES.h(p1,p2)计算
> #假定你对某流行药物能缓解60%使用者的症状感到怀疑。而一种更贵的新药如果能缓解65%
> #使用者的症状,就会被投放到市场中。此时,在研究中你需要多少受试者才能够检测到两种药物
> #存在这一特定的差异?
> pwr.2p.test(h=ES.h(0.65,0.6),sig.level = 0.05,power=0.9,alternative = "greater")
Difference of proportion power calculation for binomial distribution (arcsine transformation)
h = 0.1033347
n = 1604.007
sig.level = 0.05
power = 0.9
alternative = greater
NOTE: same sample sizes
>
> #每组1605个人

2.6、卡方检验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
##卡方检验
#常常用来评价两个类别型变量的关系。典型的零假设是变量之间独立,备择假设是不独立。
pwr.chisq.test(w=效应值,N=总样本大小,df=自由度,sig.level = ,power = )
#ES.w2(P)可以用来计算双因素列联表备择假设的效应值,P为一个假设的双因素概率表
#假设你想研究人种与工作晋升的关系。你预期样本中70%是白种人, 10%是美国黑人, 20%西班牙裔人。而且,你认为相比30%的美国黑人和50%的西班牙裔人, 60%的
#白种人更容易晋升。晋升概率如表所示。
#|人种|晋升比例|未晋升|
#|白 |0.42 | 0.28|
#|黑 |0.03 | 0.07|
#|西裔|0.10 | 0.10|
prob<-matrix(c(0.42,0.28,0.03,0.07,0.10,0.10),byrow = TRUE,nrow = 3)
ES.w2(prob)
pwr.chisq.test(w=ES.w2(prob),df=2,sig.level = 0.05,power = 0.9)
#需要369个测试者

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
##绘制功效分析图形
library(pwr)
#生成一系列相关系数和功效值
r<-seq(0.1,0.5,0.01)
nr<-length(r)
p<-seq(0.4,0.9,0.1)
np<-length(p)
#构建一个空数组存储结果
samsize<-array(numeric(nr*np),dim=c(nr,np))
#每种相关系数和功效的值对产生需要的样本数
for(i in 1:np){
for(j in 1:nr){
result <- pwr.r.test(n=NULL,r=r[j],sig.level = 0.05,power=p[i],alternative = "two.side")
samsize[j,i]<-ceiling(result$n)
}
}
#返回最小值与最大值
xrange<-range(r)
#返回最小值与最大值,向上取整
yrange<-round(range(samsize))
#产生一组彩虹色
colors<-rainbow(length(p))
#绘制坐标系
plot(xrange,yrange,type="n",xlab="相关系数",ylab="样本大小")
#每一种功效绘制曲线
for(i in 1:np){
lines(r,samsize[,i],type="l",lwd=2,col=colors[i])
}
abline(v=0,h=seq(0,yrange[2],50),lty=2,col="grey89")
abline(h=0,v=seq(xrange[1],xrange[2],0.02),lty=2,col="grey89")
title("相关性分析的样本大小估计,显著水平0.05,双尾")
legend("topright",title="功效",as.character(p),fill = colors)

InnoDB引擎对于SQL语句的加锁策略

  • 加锁状态的读、更新或删除操作一般会将其扫描到的每一个索引的记录进行加锁,它并不关心where条件是否会包含这些行,InnoDB不记得具体的where条件,仅仅知道扫描了哪些索引区间,这种锁就是通常的next-key锁,其同时封锁了在此记录之前的区间插入(gap锁)。gap锁可以被禁用,这将导致next-key锁不再使用,事务的隔离级别也会影响加锁。

  • 如果一个二级索引用在一个查询上,并且索引记录加了排它锁,InnoDB同时也睡将相应的聚簇索引记录加锁

  • 如果没有合适的索引用于你的语句,MySQL必须扫描全表,则每一行都会被加锁,这样锁住了其他所有用户的插入,创建合适的索引非常重要。

  • 对于SELECT ... FOR UPDATE或者SELECT ... LOCK IN SHARE MODE来说,其将锁加在扫描到的行上,并且在这些扫描到的行中那些不匹配结果的行(不符合where条件)会去释放锁,但是在一些情况下,这些行不会立即释放锁,因为最后的结果行和之前的原始行之间的联系在查询过程中丢失了,比如,在UNION中,扫描到的行插入了临时表进而再判断是否符合要求,这种情况下,原始的行在查询完成后锁才会释放。

  • InnoDB的加锁方式

    • SELECT ... FROM: 快照读,不加锁,除非事务的隔离级别设置为SERIALIZABLE,这种情况下查询在其查询到的记录索引上加next-key锁,如果查询通过唯一索引查询唯一的一行,则对该索引加记录锁。
    • SELECT ... FROM ... LOCK IN SHARE MODE: 对所有查询到的记录加共享的next-key锁,如果查询通过唯一索引查询唯一的一行,则对该索引加记录锁。
    • SELECT ... FROM ... FOR UPDATE: 对查询到的每一条记录设置排他的next-key锁,如果查询通过唯一索引查询唯一的一行,则对该索引加记录锁。对于查询到的记录,其还会在其他会话进行确定事务隔离级别的SELECT ... FROM ... LOCK IN SHARE MODE
    • UPDATE ... WHERE ...: 记录添加排他的next-key锁,如果查询通过唯一索引查询唯一的一行,则对该索引加记录锁。
    • 当`UPDATE修改聚簇索引记录时,其会对影响到的二级索引加共享锁,当其对二级索引的插入进行重复性检查时或者二级索引进行插入时。
    • DELETE FROM ... WHERE ...: 所有扫描到的记录加排他next-key锁,如果查询通过唯一索引查询唯一的一行,则对该索引加记录锁。
    • INSERT对插入的行加排他锁,是记录锁而不是next-key锁,不锁区间
    • 在插入行之前,会设置插入意向区间锁,此锁表示这种插入的动作在多个会话同时对同一索引区间进行插入是只要不是插入同样的位置并不需要相互等待,例如在4,7之间插入5,6,两个会话在对插入的记录加排它锁之前都会在4,7之间加插入意向区间锁,这是并不会相互等待因为行无冲突。
    • 如果在INSERT过程中,重复索引错误发生(duplicate-key error),则对这个重复的索引记录添加共享锁,此时可能发生死锁当多个会话试图插入同一行而另一个会话已经拥有一个排它锁时,这在删除该行时会发生。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      CREATE TABLE t1 (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;
      --session1
      START TRANSACTION;
      INSERT INTO t1 VALUES(1);
      --session2
      START TRANSACTION;
      INSERT INTO t1 VALUES(1);
      --session3
      START TRANSACTION;
      INSERT INTO t1 VALUES(1);
      --session1
      ROLLBACK;
      --死锁发生,1有排它锁,2,3重复错误,尝试获取共享锁,1回滚,排它锁释放,2,3都获得了共享锁,但是2,3均获取不到排它锁,发生死锁(及时发生了重复错误,insert的执行依然要最后尝试去获得排它锁)
      --session换成DELETE FROM t1 WHERE i = 1;commit;效果一样
    • INSERT ... ON DUPLICATE KEY UPDATE: 与insert的区别是在发生duplicate-key错误时,加的是排他的next-key锁

    • REPLACE: 类似没有唯一索引冲突的INSERT,另外当更新成功时候,行上加排他next-key锁。
    • INSERT INTO T SELECT ... FROM S WHERE ...: 对插入到T中的每一行加排他记录锁,如果事务的隔离级别是RC,或者innodb_locks_unsafe_for_binlog启用并且隔离级别不是序列化,Innodb将S上的查询当作一个快照读,此时没有锁,否则,S上查询到的每一行加共享的next-key锁。
    • CREATE TABLE ... SELECT ...: 类似上一个,只处理select部分的锁。
    • 当select执行类似REPLACE INTO t SELECT ... FROM s WHERE ...UPDATE t ... WHERE col IN (SELECT ... FROM s ...):InnoDB对s上的记录加共享的next-key锁。
    • 当表上有自增列时,InnoDB对自增列涉及的索引最后一个加排它锁,访问自增计数器时,InnoDB用一种特殊的AUTO-INC表锁模式,此锁仅保持到当前的SQL查询的结束部分,而不是整个事务的结束部分,AUTO-INC被持有时,其他会话无法插入。