首页 > 试题

funs

更新时间:2022-11-15 09:08:39 阅读: 评论:0

中考对策2019答案-飞艇原理


2022年11月15日发(作者:徐厚才被调查)

R语⾔数据处理(2)

本⽂⽬录如下

数据框合并

拼接合并

merge合并

计算并增加⾏列

汇总计算

分组计算

融合重铸

融合重铸的应⽤

拆分合并列

载⼊包

library(dplyr)#⾼速处理数据,取代R⾃带的⼀些函数,代码简单易记

library(tidyr)#提供⼀些其他功能

library(reshape2)

本⽂使⽤这三个包较多,如果对这⼏个包不再了解,建议先看⼀看

数据框合并

拼接合并

列相同的两个数据框可以直接纵向接在⼀起,⾏相同的两个数据框也可以横向接在⼀起。

name1<-c("Bob","Mary","Jane","Kim")

name2<-c("Bob","Mary","Kim","Jane")

weight<-c(60,65,45,55)

height<-c(170,165,140,135)

birth<-c("1990-1","1980-2","1995-5","1996-4")

accept<-c("no","ok","ok","no")

df1<-(name1,weight,height)

df2<-(name2,birth,accept)

#合并

rbind(df1,df2)

cbind(df1,df2)

#dplyr包中⾼效合并

bind_rows(df1,df2)

bind_cols(df1,df2)

merge合并

当两个数据框中有⼀列表⽰相同的含义,其他列不同时,可以按照这⼀列merge起来。

⽐如拿到两张表,分别对应两个数据框,⼀个记录了公司每个员⼯的体重,⼀个记录了公司每个员⼯的⾝⾼,他们有相同的

姓名⼀列,我们就可以把两个数据框融合成为⼀个带有姓名、⾝⾼、体重的数据框。

有的⼈可能会问,为什么不直接横向拼在⼀起,再把相同的名字列去掉?是因为如果两个数据框的名字顺序不⼀样,或者名

字不是完全相同,这样做就不⾏了。我们来看下⾯的例⼦

先创建数据框

name1<-c("Bob","Mary","Jane","Kim","Smith")

weight<-c(60,65,45,55,60)

name2<-c("Bob","Mary","Kim","Jane","Eric")

height<-c(170,165,140,135,170)

df11<-(name1,weight,stringsAsFactors=F)#加这个参数是防⽌字符串⾃动转化为因⼦

df33<-(name1,height,stringsAsFactors=F)

df22<-(name2,height,stringsAsFactors=F)#成员与前⾯不完全⼀样

先使⽤基础的merge函数

merge(df11,df33)#⾃动根据相同的列名匹配

merge(df11,df22,by.x="name1",by.y="name2")#没有相同的列名则指定根据这两列融合

#上⾯默认保留了df11和df22共有的⾏

merge(df11,df22,by.x="name1",by.y="name2",all=T)#保留所有出现过的⾏,没有的显⽰NA

merge(df11,df22,by.x="name1",by.y="name2",all.x=T)#保留所有x的⾏

merge(df11,df22,by.x="name1",by.y="name2",all.y=T)#保留所有y的⾏

下⾯使⽤dplyr包

inner_join(df11,df33)#⾃动根据相同的列名匹配

full_join(df11,df22,by=c("name1"="name2"))

left_join(df11,df22,by=c("name1"="name2"))#只保留前者的⾏

right_join(df11,df22,by=c("name1"="name2"))#只保留后者的⾏

mi_join(df11,df22,by=c("name1"="name2"))#保留共有的⾏,同时只返回前者的列

anti_join(df11,df22,by=c("name1"="name2"))#返回后者没有的前者的⾏,同时只返回前者的列

计算并增加⾏列

创建数据框

name1<-c("Bob","Mary","Jane","Kim")

weight<-c(60,65,45,55)

height<-c(170,165,140,135)

df1<-(name1,weight,height)

R基础函数

df2<-transform(df1,BMI=weight/height^2)#第⼀种⽅法

df2

df1$BMI<-df1$weight/df1$height^2#第⼆种⽅法,每⼀步都要$,很⿇烦

df1

使⽤dplyr包中的函数

mutate(df1,BMI=weight/height^2)

汇总计算

apply(df1[,-1],2,mean)#R基础函数

dplyr包中的summari系列函数

summari(df1,arv_weight=mean(weight),arv_height=mean(height))

上⾯这种⽅式是⼀般⼈都会⽤的,但是如果没有看过dplyr包的⽂档,就不知道还有summari_all等函数。当需要对每列都

进⾏计算时,或者选择某⼀些列计算,只是summari⼀个⼀个指定就会⾮常⿇烦。下⾯我们介绍⼀些批量筛选计算的函

数。

为了更好地说明问题,我们改⼀下数据框

name1<-c("Bob","Mary","Jane","Kim")

weight<-c(60,65,45,55)

height<-c(170,165,140,135)

weta<-1:4

df1<-(name1,weight,height,weta)

summari_all和summari_if

对所有列进⾏计算或者根据列的数据类型选择计算

summari(df1,avg_weight=mean(weight),avg_height=mean(height))#很⿇烦地每个都指定

summari_all(df1[-1],mean)#对选出来的所有列都进⾏计算

summari_if(df1,c,mean)#检验出所有是数值的列,全部求均值

summari_at配合vars的⽤法

筛选出符合条件的列名对应的列

summari_at(df1,vars(weight,height,weta),mean)#配合vars函数,⼀次选择多列

summari_at(df1,vars(weight:weta),mean)#从哪到哪

u<-c("weight","height")

summari_at(df1,vars(one_of(u)),mean)#可以接字符串向量

summari_at(df1,u,mean)#也可以直接接字符串向量

summari_at(df1,u,mean,trim=1)#mean的参数可以接在后⾯

summari_at(df1,vars(contains("eig")),mean)#匹配含有的

summari_at(df1,vars(matches(".t.")),mean)#使⽤正则表达式

summari_at(df1,vars(starts_with("w")),mean)#匹配以此为开头的

summari_at(df1,vars(ends_with("ht")),mean)#匹配以此为结尾的

summari_at(df1[,-1],vars(everything()),mean)#选择所有列

funs的⽤法

summari_all(df1[,-1],funs(mean,sum))

summari_all(df1[,-1],funs(sum(.*2)))#数据⽤.表⽰

summari_all(df1[,-1],funs(medi=median))#指定得到的列后缀名

summari_all(df1[,-1],funs("in"=median))#或者加引号

mutate_all(df1[,-1],funs(.^2))

结合使⽤

summari_if(df1,c,funs(mean,sum))

summari_at(df1,vars(ends_with("t")),funs(mean,sum))

分组计算

⾸先创建我们需要的数据集

name1<-c("Bob","Mary","Jane","Kim")

weight<-c(60,65,45,55)

height<-c(170,165,140,135)

accept<-c("no","ok","ok","no")

df<-(name1,weight,height,accept)

R基础函数

tapply(df$height,df$accept,mean)#使⽤tapply函数,按照accept分类

with(df,{#使⽤aggregate函数

aggregate(height,by=list(accept),FUN=mean)

})

使⽤dplyr包中的函数

group_df<-group_by(df,accept)

summari(group_df,arv_height=mean(height),count=n())#其中n()是查数的意思

#使⽤扩展函数

summari_all(group_df[,-1],mean)

summari_if(group_df,c,mean)

summari_at(group_df,vars(contains("eigh")),funs(sum,mean))

dplyr包中的主要功能我们就讲到这⾥,除了以上功能,这个包还改写了很多基础函数,使其使⽤更⽅便,运⾏速度更快,感

兴趣的读者可以查看帮助⽂档⾃⾏学习。

融合重铸

说到融合重铸,就不得不使⽤这张经典的图(来⾃《R语⾔实战》),这张图清晰的展现了融合重铸到底做了什么

这⾥我们使⽤reshape2包和tidyr包分别完成融合重铸功能。

reshape2

上⾯这张图对应的代码就是reshape2包中的函数

names(airquality)<-tolower(names(airquality))

View(airquality)

aqm<-melt(airquality,id=c("month","day"),=TRUE)#除了month和day两列,其他列摞起来,为了等长,m和d列循环对齐

dcast(aqm,day+variable~month)#保持day和variable不变,month中的元素分类映射到列上去

dcast(aqm,variable+day~month)#换⼀下顺序,重复的variable连在⼀起,对应不⼀样的day,这样的⽅式排列

dcast(aqm,day~variable+month)#只保留day列

#加⼊计算

dcast(aqm,day~month,mean)#没出现的那个变量被平均掉了

#dcast和acast区别

dcast(aqm,variable+month~day)

acast(aqm,variable+month~day)#acast和dcast的功能基本上相同,只是dcast会把分组信息作为⼀列或⼏列显⽰,⽽acast会将其作为⾏名

acast(aqm,day~month,mean)#保留的列作为合并在⼀起作为列名

acast(aqm,variable~month~day)#acast多出来的功能,⽣成⼀个三维数组,按照day的值分成31个矩阵

tidyr包

有融合和重铸的函数,但是在重铸⽅⾯功能弱⼀些

aqg<-gather(airquality,group,value,ozone:temp)#融合,和reshape2的不同在于输⼊的是被转换的列

spread(aqg,group,value)#还原

spread(aqg,month,value)#输⼊要被转化到列名的列和值,好像⼀次只能转化⼀列作为列名

融合重铸的应⽤

让我们把融合重铸计算实现的功能和分组计算做⼀下对⽐。

假设我们拿到的数据是下⾯这个样⼦的。按照⽉⽇,分不同组别汇总在⼀起的两列变量值

df<-mutate(aqm,newvalue=value+rnorm(2,0,50))

colnames(df)<-c("month","day","group","value1","value2")

View(df)#我们可以看⼀看现在拿到的数据

我们⾸先实现如下功能

根据group分组计算两个value的均值

根据month和group分组计算两个value的均值

根据month和group分组计算每组个数

使⽤分组计算来实现

#根据group分组计算两个value的均值

df_grp1<-group_by(df,group)

summari_at(df_grp1,vars(value1,value2),mean)

#根据month和group分组计算两个value的均值

df_grp2<-group_by(df,month,group)

summari_at(df_grp2,vars(value1,value2),mean)

#根据month和group分组计算每组个数

summari(df_grp2,count=n())

使⽤融合重铸来实现

df_melt<-melt(df,id=c("month","day","group"))

#根据group分组计算两个value的均值

dcast(df_melt,group~variable,mean)

#根据month和group分组计算两个value的均值

dcast(df_melt,month+group~variable,mean)

#根据month和group分组计算每组个数

dcast(df_melt,month+group~variable,length)

从上⾯来看,实现分组计算的功能⼆者没有太⼤区别,毕竟这就是分组计算本⾝在做的事情,不过当需要按照多种分组来计

算时,融合重铸不需要重新设置组别,显然会更⽅便。

不过融合重铸也要注意⼀点,如果数据列数⾮常多,⽽且有的是字符串,或者有的列不是你需要计算的,要事先只提取出你

需要的,再融合重铸。

下⾯我们说⼀说融合重铸擅长的部分

如果要不区分value1和value2,算整体按照month和group分组后的均值

上⾯计算结果值是⼀个矩阵,想要把数值⽤⼀列表⽰

按照⽉份拆分成多个矩阵,每⼀个矩阵表⽰group和⽇期的对应

#如果要不区分value1和value2,算整体按照month和group分组后的均值

(mg<-dcast(df_melt,month~group,mean))#上⾯计算结果值是⼀个矩阵,想要⽤⼀列表⽰

melt(mg,id="month")

#按照⽉份拆分成多个矩阵,每⼀个矩阵表⽰group和⽇期的对应

u<-acast(df_melt,group~day~month)#使⽤acast返回⼀个三维数组

拆分合并列

我们现在要把⼀列这种类型”1990-1”的数据拆分成两列”1990”和”1”这样的数据,使⽤tidyr包中的parate函数

library(tidyr)

name1<-c("Bob","Mary","Jane","Kim")

birth<-c("1990-1","1980-2","1995-5","1996-4")

df<-(name1,birth)

(df1<-parate(df,birth,into=c("year","month"),p="-"))

parate_rows(df,birth,p="-")#拆分完放在⼀列⾥⾯显⽰

#其实parate_rows相当于使⽤parate之后进⾏了融合,再更换⼀下顺序

parate(df,birth,into=c("year","month"),p="-")%>%gather(group,birth,year:month)

tidyr包中很多函数都是成对出现的,unite函数是和parate函数反向的函数,可以将它得到的结果还原

unite(df1,birth,year,month,p="-")

到这⾥,我们就把数据处理的整体框架讲述了⼀遍,主要针对数据的计算与变形,覆盖了dplyrtidyrreshape2包的使⽤⽅

法。本专题下⼀篇,我们会使⽤包来重新完成这整个框架

本文发布于:2022-11-15 09:08:39,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/88/23343.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:funs
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图