手记

R语言:数据变换和重塑

数据分析的工作,80%的时间耗费在处理数据上,而数据处理的主要过程可以分为:分离-操作-结合(Split-Apply-Combine),也就是说,首先,把数据根据特定的字段分组,每个分组都是独立的;然后,对每个分组按照业务需求执行转换;最后,把转换后的结果组合在一起。在数据处理中,经常需要循环访问数据,R语言是矢量化的,天生具有处理循环操作的优势。

一,简单的数据变换

在研究数据时,有时需要对数据按照特定的字段进行分组,然后统计各个分组的数据,这就是SQL语法中的分组-聚合操作,使用aggregate()函数对数据进行简单的数据处理。

aggregate()函数用于把数据分离为单独的子集,为每一个子集计算聚合值,然后把聚合值结合(combine)在一起返回。

aggregate(formula, data, FUN, ...,subset, na.action = na.omit)

参数注释:

  • formula:指定formula对象,包括符号“ ~”,以及在符号“~”两侧的变量,左侧代表要计算聚合值的变量(聚合变量),右侧代表分组的变量,例如,price~cut,函数依据分组变量,把数据分离为多个单独的子集。

  • data:指定操作的数据框;

  • FUN:该参数用于指定函数,该函数应用在符号“~”左侧的变量;

  • ...:指定传递给FUN函数的其他参数;

  • subset:向量类型,可选参数,用于指定data的观测子集;

  • na.action: 如何处理缺失值,默认为忽略NA。如果不选择na.omit,则需指定函数去处理NA。

1,加载示例数据

使用ggplot2包中的diamonds数据集做为示例数据

> install.packages('ggplot2')> library(ggplot2)> data("diamonds")

data()函数的作用是加载指定的数据集,本例将加载ggplot2包中的diamonds数据集,这个数据集在下文直接引用。

2,单个分组变量

使用aggregate() 函数操作diamonds数据集,按照cut字段分组,函数mean的作用是为每个分组计算prince的平均值:

> aggregate(price~cut,diamonds,mean)

3,多个分组变量

aggregate()函数能够添加多个分组变量,只需要在formula右侧添加变量,并用加号“+”隔离:

> aggregate(price~cut+color,diamonds,mean)         cut color    price1       Fair     D 4291.0612       Good     D 3405.3823  Very Good     D 3470.467....

4,多个聚合变量

aggregate()函数能够添加多个聚合变量,只需要在formula左侧,使用函数cbind()把两个变量组合起来:

> aggregate(cbind(price,carat)~cut,diamonds,mean)        cut    price     carat1      Fair 4358.758 1.04613662      Good 3928.864 0.84918473 Very Good 3981.760 0.80638144   Premium 4584.258 0.89195495     Ideal 3457.542 0.7028370

5,多个分组变量和多个聚合变量

aggregate()函数能够formular对象的两侧分别添加多个变量,按照多个分组变量和多个聚合变量执行聚合运算

> aggregate(cbind(price,carat)~cut+color,diamonds,mean)         cut color    price     carat1       Fair     D 4291.061 0.92012272       Good     D 3405.382 0.7445166....

二,数据变换(dplyr包)

dplyr包提供灵活的数据操作,用于对数据框执行转化和重塑,这个包是plyr包的升级版本,侧重于处理数据框对象,因此其名字带d(data frame),dplyr包是R开发人员必学必会的包。

dplyr包有三个主要的目标:

  •  更加灵活和简单地处理数据框;

  • 使用内存,提高数据处理的性能;

  • 使用相同的接口处理数据,无论数据存储在何处,无论是在数据框中,数据表或数据库。

1,tlb类型dplyr包不是默认安装的包,在使用之前,需要使用以下命令安装和引用dplyr包:

install.packages("dplyr")library(dplyr)

dplyr包只能用于tibble(简称tbl)类型的对象,tibble 类型是dplyr包特有的对象类型(data frame tbl / tbl_df)。在利用dplyr包处理数据之前,建议把数据框装载成tibble类型,可以调用 tbl_df()函数把数据框类型转化成 tibble 类型的数据对象:

> df <- tbl_df(diamonds)

2,投影函数(select)

从tbl对象中,选择特定的数据列显示,select()函数的第一个参数是tibble对象,后续的参数是tbl对象中的变量名:

> select(df,carat,cut,color)

2,筛选函数(filter)

从tbl对象中,按照特定的条件过滤数据:

> filter(df,color=='E')

3,转换函数(mutate)

根据tbl对象中的数据,应用指定的公式,派生新的数据列,或重写已经存在的数据列:

> mutate(df,avg_ct=price/carat)

4,汇总函数(summarize)

对tbl对象执行聚合运算,如果tbl对象已经被分组,那么单独对每个分组进行聚合运算:

> summarize(df,avg_prince=mean(price),avg_ct=mean(carat))

5,分组函数(group_by)和移除分组(ungroup)

使用group_by()函数对tbl对象执行分组,被分组之后,tbl对象处于分组状态,可以使用ungroup函数,移除tbl对象的分组状态。

group_by(df,color)

6,排序函数(arrange)

arrange()函数对tbl变量进行排序,默认是按照字段的升序值排序,使用desc(field),可以按照字段的降序值排序:

> arrange(df,color)

7,管道操作符(%>%)

管道操作符(%>%)用于把前一步操作的结果集(变量类型是tbl)传递到给函数的第一个参数中,同时函数的第一个参数可以省略,例如:

> df %>% group_by(color) %>% summarize(mean(price))# A tibble: 7 x 2  color `mean(price)`  <ord>         <dbl>1     D      3169.9542     E      3076.7523     F      3724.8864     G      3999.1365     H      4486.6696     I      5091.8757     J      5323.818

8,连接操作(join)

dplyr包还提供了连接(join)操作,

inner_join(x, y, by = NULL, copy = FALSE, suffix = c(".x", ".y"), ...)left_join(x, y, by = NULL, copy = FALSE, suffix = c(".x", ".y"), ...)right_join(x, y, by = NULL, copy = FALSE, suffix = c(".x", ".y"), ...)full_join(x, y, by = NULL, copy = FALSE, suffix = c(".x", ".y"), ...)semi_join(x, y, by = NULL, copy = FALSE, ...)anti_join(x, y, by = NULL, copy = FALSE, ...)

参数注释:

  • by:设置两个数据集用于匹配的字段名,默认使用全部的同名字段进行匹配,如果两个数据集需要匹配的字段名不同,可以直接用等号指定匹配的字段名,例如, by = c("a" = "b"),表示用x.a和y.b进行匹配。

  • copy:如果两个数据集来自不同的数据源,copy设置为TRUE时,会把数据集y的数据复制到数据集x中,出于性能上的考虑,需要谨慎设置copy参数为TRUE。

  • suffix:合并后的数据集中同名变量,会自动添加suffix中设置的后缀加以区分。

9,集合操作(set)

#取两个集合的交集intersect(x,y, ...)#取两个集合的并集,并进行去重union(x,y, ...)#取两个集合的并集,不去重union_all(x,y, ...)#取两个集合的差集setdiff(x,y, ...)#判断两个集合是否相等setequal(x, y, ...)

10,绑定操作

dplyr包提供了按行/列合并数据集的函数,合并的对象为数据框,也可以是能够转换为数据框的列表。按行合并函数bind_rows()通过列名进行匹配,不匹配的值使用NA替代,类似于base:: rbind()函数。按列合并函数bind_cols()通过行号匹配,因此合并的数据框必须有相同的行数,函数类似于base:: cbind()函数。原数据集行名称会被过滤掉。

#按行合并,.id添加新列用于指明合并后每条数据来自的源数据框bind_rows(...,.id = NULL)#按列合并bind_cols(...)#合并数据集combine(...)

11,排名操作

row_number(x)ntile(x, n)min_rank(x)dense_rank(x)percent_rank(x)cume_dist(x)

例如,对一个向量的元素进行排序:

x <- c(5, 1, 3, 2, 2, NA)row_number(x)

12,去重

对数据对象去重

distinct(data, ..., keep_all = FALSE)

参数注释:

  • data:tbl对象

  • ... :可选的变量,用于指定去重的变量,如果去重的变量不唯一,那么只保留第一个观测

  • keep_all:设置为TRUE时,所有的变量都保留到.data,如果...的组合不唯一,那么只保留第一行的观测的各个变量值

13,计数

统计数据集中无重复值的数量

n_distinct(..., na.rm = FALSE)

统计各个分组的观测数量,只能用于 summarise(), mutate() 和 filter() 中

n()carriers <- group_by(flights, carrier)summarise(carriers, n())mutate(carriers, n = n())filter(carriers, n() < 100)

三,数据重塑(reshape2包)

reshape2包用于实现对宽数据及长数据之间的相关转换,由于reshape2包不在R的默认安装包列表中,在第一次使用之前,需要安装和引用:

install.packages("reshape2")library(reshape2)

大致说来,首先把数据融合(melt),以使每一行都有唯一的标识符-变量组合,然后把数据重塑(cast)为想要的任何形状。在重塑过程中,可以使用任何函数对数据进行整合。

创建示例数据,这种数据显示叫做数据的短格式

> ID <- c(1,1,2,2)> Time <- c(1,2,1,2)> X1 <- c(5,3,6,2)> X2 <-c(6,5,1,4)> mydata <- data.frame(ID,Time,X1,X2)> mydata  ID Time X1 X21  1    1  5  62  1    2  3  53  2    1  6  14  2    2  2  4

1,融合

数据集的融合使指把数据集重构为特定的格式:每个观测变量独占一行,每行都有唯一确定每个观测所需要的标识符变量:

> md <- melt(mydata, id=c("ID","Time"))> md  ID Time variable value1  1    1       X1     52  1    2       X1     33  2    1       X1     64  2    2       X1     25  1    1       X2     66  1    2       X2     57  2    1       X2     18  2    2       X2     4

数据融合之后,变成所谓的长格式

注意:必须指定唯一确定每个观测所需的变量(ID和Time),而表示观测变量名的变量(X1和X2)由程序自动创建,从结果中可以看出,函数自动创建了两个变量:variable和value

2,重塑

dcast()函数用于读取已融合的数据框(d是指data frame),并使用formula和用于整合数据的函数把数据集重塑,

dcast(data, formula, fun.aggregate = NULL, ..., margins = NULL,  subset = NULL, fill = NULL, drop = TRUE,  value.var = guess_value(data))

参数 formula用于指定输出的结果集格式,formula的格式是:

rowvar1 + rowvar2 +...  ~  colvar1 + colvar2 +...

在该公式中,rowvar 定义了保留的变量名,以唯一确定各个观测;colvar定义了剔除的变量名,以确定各个变量(variable)的值。

例如,把数据的长格式转化为数据的短格式:

> dcast(md,ID+Time~variable)  ID Time X1 X21  1    1  5  62  1    2  3  53  2    1  6  14  2    2  2  4

例如,把Time剔除,按照ID和variable来显示变量variable的值:

> dcast(md,ID+variable~Time)  ID variable 1 21  1       X1 5 32  1       X2 6 53  2       X1 6 24  2       X2 1 4

例如,只保留ID,计算变量的平均值:

> dcast(md,ID~variable,mean)  ID X1  X21  1  4 5.52  2  4 2.5


0人推荐
随时随地看视频
慕课网APP