第三章 图形进阶
人类非常善于从视觉呈现中洞察关系,对于同样的信息,图形相比于其他信息的呈现方式更能被发现其中的模式,供人们参考分析,做出决策
3.1.使用图形
plot() 是R中作图的一个泛型函数(输出会根据所绘对象类型的不同而改变)。
3.2.图形参数
3.2.1.通过函数par()来指定,调用格式为par(optionname= value1,optionname=value2, .....),添加参数no.readonly = TRUE 可以生成一个可以修改当前图形参数列表
eg:
> dose <- c(20,30,40,45,60)
> drugA <- c(10,20,30,40,50)
> drugB <- c(20,24,28,31,35)
> plot(dose,drugA,type="b")
>
> opar <- par(no.readonly = TRUE)
#(lty=2):线条类型为虚线 (pch =17):实心三角
> par(lty=2,pch=17)
> plot(dose,drugA,type="b")
> par(opar)
3.2.2.直接为高级绘图函数提供optionname = value的键值对,指定的选项仅对本幅图有效,并非所有绘图函数都允许指定全部可能的图形参数,使用前参考特定函数的帮助文档
plot(dose,drugA,type="b",lty=2,pch=17)
调试的时候遇到这样一个问题:Error in plot.new() : figure margins too large,这是因为plot绘图区域太小导致,全屏Rstudio,把右下方plots 区域调大即可
3.3,符号、线条和颜色
plot(dose,drugA,type="b",lty=2,pch=25,lwd = 3,cex = 2,col="#244aaa")
pch:绘制点的符号(详细参见P48-图3-4)
cex:符号、字体、字样大小(详细参见P50-表3-4)
font:指定字体族、字号和字体参数(详细参见P51-表3-5)
lty:指定线条类型 (详细参见P48-图3-5)
lwd:指定线条的宽度
col:默认绘制颜色 (详细参见P49-表3-3)
3.4.图形尺寸与边界
pin() :用英寸表示图形的尺寸(宽、高)
mai():数值向量表示边界大小,顺序为(下左上右,单位英寸)
mar():数值向量表示边界大小,顺序为(下左上右,单位英分默认c(5,4,4,2)+0.1)
3.5.坐标轴相关属性的设置
3.5.1 高级绘图函数(plot、hist、boxplot)可以自行设定坐标轴的参数
#mian:标题; sub :副标题; X和Y坐标轴的标签(xlab,ylab); 坐标轴范围(xlim,ylim)
>plot(dose,drugA,type="b",col="red",lty=2,pch=2,lwd=2,main = "main title for drugA result",sub="subject title for drugA result",xlab="Dosage",ylab="Drug Response",xlim = c(10,70),ylim=c(10,70))
3.5.2 使用title()函数为图形增加标题和坐标轴标签,坐标轴参数参考(p54 表3-7)
#先调用plot()加入ann= FALSE属性来移除上次添加的
plot(dose,drugA,type="b",col="red",lty=2,pch=2,lwd=2,main = "main title for drugA result",sub="subject title for drugA result",xlab="Dosage",ylab="Drug Response",xlim = c(10,70),ylim=c(10,70),ann = FALSE)
> title(main="test main title",sub="test subtitle", xlab ="x",ylab = "y" )
>
3.6.参考线 调用abline()
3.7.图例
当图形中包含的数据不止一组时,图例可以有效的分辨出每条图形、扇形区域或折线各代表哪一类数据,可以使用legend()来添加图例,格式为 legend(location,title,legend,...)
实例:
>opar <- par(no.readonly = TRUE)
#增加标签
> par(lwd = 2,cex = 1.5,font.lab =2)
#绘制图形drugA
> plot(dose,drugA,type="b",pch=15,lty=1,col="red",ylim = c(0,60),main = "drugA vs drugB",xlab = "drug dosage",ylab = "drug response")
#绘图drugB
> lines(dose, drugB,type="b",pch=17,lty=2,col="blue")
> abline(h=c(30),lwd=1.5,lty=2,col="gray")
#添加刻度线
> library(Hmisc)
Error in library(Hmisc) : 不存在叫‘Hmisc’这个名字的程辑包
> install.packages("Hmisc")
#忽略警告(默认warn =0,设置为-1就不会显示了)
> options(warn = -1)
> minor.tick(nx=3,ny=3,tick.ratio = 0.5)
> legend("topleft",inset=.05,title="Drug Type",c("A","B"),lty=c(1,2),pch=c(15,17),col=c("red","blue"))
> par(opar)
3.8.文本标注和数学标注图形组合
3.8.1使用text():向绘图区域内添加文本,mtext()向图形四个边界之一添加文本
3.8.2 数学标注:使用plotmath()
3.8.3 图形组合:使用par() 和layout() 可以组合多幅图形为一副总括图形
3.9.图形的精细控制
> opar <- par(no.readonly = TRUE)
> par(fig=c(0,0.8,0,0.8))
#设置散点图
> plot(mtcars$wt,mtcars$mpg,xlab="Miles Per Gallon",ylab="Car weight")
#箱线图
> par(fig=c(0,0.8,0.55,1),new =TRUE)
> boxplot(mtcars$wt,horizontal = TRUE,axes = FALSE)
Error in plot.new() : figure margins too large
> boxplot(mtcars$wt,horizontal = TRUE,axes = FALSE)
> par(fig=c(0.65,1,0,0.8),new = TRUE)
> boxplot(mtcars$mpg,axes=FALSE)
> mtext("Enhanced Scatterplot",side=3,outer = TRUE,line=-3)
> par(opar)
第四章 基本数据管理
4.1.创建新变量
可以使用transform()创建
> mydata <- data.frame(x1 = c(1,2,3,4),x2 = c(2,4,6,8))
> mydata
#新变量sumx 和meanx 将被保存到mydata数据框中
> mydata <- transform(mydata,sumx = x1+x2,meanx = x1*x2)
> mydata
4.2 变量的重编码和重命名
重编码可以实现 1:将一个连续型变量修改为一组类别值
2.将误编码的值替换为正确值
变量的重命名:1.调用fix( );调用出编辑器,点击变量名直接重命名
2.使用代码的通过 names() ,或者通过plyr包的rename()函数
4.3 缺失值
4.3.1.查看缺失值:使用 is.na()函数,缺失值将返回TRUE 不是缺失值将返回FALSE
4.3.2.重编码缺失值:确保数据中所有缺失数据都在分析前编码为缺失值,否则分析结果将没有意义
4.3.3.分析中排除缺失值:1.多数数值函数都有一个na.rm=true的参数,可以剔除缺失值,并使用剩余值进行运算, 2.使用 na.omit()移除所有含有缺失值得数据行
4.4 日期值
4.4.1.日期的输入和输出 :使用as.Date(x,"input_format")以固定格式读入日期,使用format(x,format="output_format")
> today <- Sys.Date()
> today
[1] "2017-04-08"
> format(today,format="%y/%m/%d")
[1] "17/04/08"
4.4.2.将日期转换为字符型变量: as.charactor(dates);
4.5 类型判断和转换 参考(P78-表4.5 )
4.6 数据的排序 :使用order()函数默认为升序,在变量前加"-"号即可降序
4.7 数据集的合并
4.7.1 数据框添加列 :使用merge()
4.7.2 数据框中添加行:使用rbind(),横向合并两个数据框或者矩阵,使用cbind() 但这两个数据集必须含有相同的行数
4.8 选择数据的子集进入观测 :使用subset(),例如下示例:
name <- c("lily","danial","peter","pank")
> age <- c(12,15,27,37)
> student <- data.frame(name,age)
> student
name age
1 lily 12
2 danial 15
3 peter 27
4 pank 37
> newdata <- subset(student,age >20,select =c(name,age))
> newdata
name age
3 peter 27
4 pank 37
>
实战:分析 朝阳医院2016年销售数据.xlsx,查看每周的销售额额变化情况,下面是部分数据展示
购药时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额
1 001616528 236701 三九感冒灵 7 196.0 182.00
2 001616528 236701 三九感冒灵 3 84.0 84.00
3 2016-01-06 星期三 00703438 236701 3 84.0 73.92
4 2016-01-11 星期一 236701 三九感冒灵 1 NA 28.00
5 2016-01-15 星期五 00101554328 236701 三九感冒灵 8 224.0 NA
6 2016-01-20 星期三 0013389528 三九感冒灵 1 28.0 28.00
7 2016-01-31 星期日 00101464928 236701 三九感冒灵 2 56.0 56.00
8 2016-02-17 星期三 0011177328 236701 三九感冒灵 5 149.0 131.12
9 2016-02-22 星期一 0010065687828 236701 三九感冒灵 1 29.8 26.22
10 2016-02-24 星期三 0012602828 236701 三九感冒灵 4 119.2 104.89
.
.
.
第一步: 读取excel 表的数据
> install.packages("openxlsx")
> library("openxlsx")
> readFilePath <- "D:/R/RStudioWorkspace/project3_20170408/朝阳医院2016年销售数据.xlsx"
> exceldata <- read.xlsx(readFilePath)
第二步:数据预处理步骤
1.获取购药时间不为空的数据,删除所有含有缺失数据的行
> exceldata <- na.omit(exceldata)
2.将列名重命名为英文形式
> names(exceldata) <- c ("time","cardno","drugId","drugName","saleNumber","virualmoney","actualmoney")
3.整理日期为xxxx-xx-xx的形式
> exceldata$time <- as.Date(exceldata$time,"%Y-%m-%d")
4.把销售数量等一些需要运算的参数转换为数值型
> exceldata$saleNumber <- as.numeric(exceldata$saleNumber)
> exceldata$virualmoney <- as.numeric(exceldata$virualmoney)
> exceldata$actualmoney <- as.numeric(exceldata$actualmoney)
5.按销售时间进行降序排序
exceldata <- exceldata[order(exceldata$time,decreasing = FALSE),]
6.计算月均消费次数、月均消费金额、客单价来评估消费趋势
#去除重复数据赋值给kpi1
kpi1 <- exceldata[!duplicated(exceldata[,c("time","cardno")]),]
#总消费次数
> cunsumeNumber <- nrow(kpi1)
#计算出月份数
> startime <- kpi1$time[1]
> endtime <- kpi1$time[nrow(kpi1)]
> day <- endtime - startime
> day <- as.numeric(day)
> month <-day %/% 30
#月均消费次数 = 总消费次数/月份数
> monthcunsume <- cunsumeNumber/month
#月平均消费金额
> totalmoney <- sum(exceldata$actualmoney,na.rm = TRUE)
> monthmoney <- totalmoney/month
#客单价
> pct <- totalmoney/cunsumeNumber
#计算每周的消费金额
> week <- tapply(exceldata$actualmoney,format(exceldata$time,"%Y-%U"),sum)
#开始绘图
> week <- as.data.frame.table(week)
#修改数据名称
names(week) <- c("time","actualmoney")
week$time <- as.character(week$time)
#新增列
> week$timeNumber <- c(1:nrow(week))
#使用plot 进行绘图
> plot(week$timeNumber,week$actualmoney,xlab="时间(年份_第几周)",ylab="消费金额",xaxt = "n",main="2016朝阳医院每周消费额变化曲线",col = "blue",type="b")
#完善坐标轴,增加刻度
axis(1,at=week$timeNumber,labels = week$time,cex.axis= 0.8)
#增加图例 ,让计算结果更加直观
> monthmoney <- round(monthmoney,2)
> pct <- round(pct,2)
#拼接字符
> pctStr <- paste("客单价:",pct)
> monthmoneyStr <- paste("月均消费额:",monthmoney)
> monthcunsumeStr <- paste("月均消费次数:",monthcunsume)
#添加图例
legend("topright",inset = 0.05,c(monthcunsumeStr,monthmoneyStr,pctStr),col = "blue")
第三步:数据分析
显示结果如下: