“dplyr数据变换”
这一章主要介绍
- filter():筛选
- mutate():建立新的变量
- group_by():
- summarise():
- %>%:管道操作
1.filter():筛选
第一个参数是数据框,后面的是逻辑值
例如
dplyr::filter(iris,Sepal.Length>7)
x==y
x !=y (x和y不等)
x %in% c(“a”,“b”,“c”)(x属于右侧)
x>y,x>=y,x<y,x<=y
用逻辑运算符组合起来
!x
x&y
X|y
xor(x,y) (异或)
library(dplyr)
library(ggplot2)
library(dplyr)
head(iris)
dplyr::filter(iris,Sepal.Length>7)
我们以钻石数据集为例,首先看一下钻石数据集x维还有y维的分布。
library(ggplot2)
library(dplyr)
ggplot(diamonds,aes(x,y))+geom_bin2d()
大部分在对角线附近,但是有一些异常值,比如等于零的。
filter(diamonds,x==0|y==0)
diamonds_ok <- filter(diamonds,x>0,y>0,y<20)
ggplot(diamonds_ok,aes(x,y))+geom_bin2d()+
geom_abline(slope = 1,colour="white",size=1,alpha=0.5)
#geom_bin2d():直方图的二维推广。geom_abline:添加参考线
filter()筛选的是观测,仅包含那些逻辑值都为TRUE的观测,所以对于NA是直接删除的。
2.mutate():建立新的变量
mutate()可以建立新的变量
针对钻石数据我们想看一下对称程度(即x与y的差值),还有钻石的大小(对角线的长度)。
diamonds_ok2 <- mutate(diamonds_ok,sym=x-y,size=sqrt(x^2+y^2))
head(diamonds_ok2)
ggplot(diamonds_ok2,aes(size,sym))+
stat_bin2d()
我们关注的是对称程度也就是x-y的绝对值。
ggplot(diamonds_ok2,aes(abs(sym)))+geom_histogram(binwidth = 0.1)
我们可以进一步筛选差值在0.2以内的作图看一下。
diamonds_ok3 <- filter(diamonds_ok2,abs(sym)<0.2)
ggplot(diamonds_ok3,aes(abs(sym)))+geom_histogram(binwidth = 0.01)
从这个图里我们看到大多数钻石都接近对称,但是只有极少数是完全对称的。
3.group_by():定义分组变量,summarise():汇总总结
dplyr分两步完成汇总
1.用group_by定义分组变量
2.用一行summarise代码描述如何对每组汇总。
3.1group_by这个函数只是定义分组变量,并没有改变数据的结构。
3.2summarise():汇总总结,和一些函数协作。
- 计数:n()、n_distinct(x)
- 中间值:mean(x)、median(x)
- 离散程度sd()、mad(x)、IQR(x)
- 极端值quartile(x)、min(x)、max(x)
- 位置first()、last()、nth()
要想看不同净度的钻石的平均价格可以通过下面的代码实现。
by_clarity <- group_by(diamonds,clarity)
sum_clarity <- summarise(by_clarity,price=mean(price))
sum_clarity
ggplot(sum_clarity,aes(clarity,price))+
geom_line(aes(group=1),colour="grey80")+geom_point(size=2)
这个图中净度更高时价格却低了。在后面会解决。
下面我们对刚才的分净度平均价格做一个补充:增加每组的计数和上下四分位点。这显示出均值对这个数据的汇总效果并不好,因为价格的分布是偏态的:在某些组内,均值甚至比上四分位数还高。
by_clarity <- diamonds%>%
group_by(clarity)%>%
summarise(
n=n(),mean=mean(price),lq=quantile(price,0.25),up=quantile(price,0.75)
)
by_clarity
ggplot(by_clarity,aes(clarity,mean))+
geom_linerange(aes(ymin=lq,ymax=up))+
geom_line(aes(group=),colour="grey50")+
geom_point(aes(size=n))
我们也可以多个变量分组。
接下来的例子就是展示计算一个展现切工和深度关系的频率多边形。
cut_depth <- summarise(group_by(diamonds,cut,depth),n=n())
cut_depth <- filter(cut_depth,depth>55,depth < 70)
cut_depth
ggplot(cut_depth,aes(depth,n,colour=cut))+geom_line()
# 我们可以将计数转换为比例,这样更方便在各个切工中比较
cut_depth <- mutate(cut_depth,prop=n/sum(n))
ggplot(cut_depth,aes(depth,prop,colour=cut))+geom_line()
4.管道操作
%>% 相当于将左边的作为右边函数的第一个参数。
快捷键ctrl+shift+M
例如:f(x,y)等价于x %>% f(y)
g(f(x,y),z)等价于x %>% f(y) %>% g()
library(ggplot2)
library(dplyr)
cut_depth <- group_by(diamonds,cut,depth)
cut_depth <- summarise(cut_depth,n=n())
cut_depth <- filter(cut_depth,depth>55,depth<70)
cut_depth <- mutate(cut_depth,prop=n/sum(n))
cut_depth
library(ggplot2)
library(dplyr)
library(tidyr)
cut_depth1 <- diamonds%>%
group_by(cut,depth)%>%
summarise(n=n())%>%
filter(depth>55,depth<70)%>%
mutate(prop=n/sum(n))
cut_depth1