【R语言】plyr包和dplyr包

一、plyr包

plyr扩展包主要是实现数据处理中的"分割-应用-组合"(split-apply-combine)策略。此策略是指将一个问题分割成更容易操作的部分,再对每一部分进行独立的操作,最后将各部分的操作结果组合起来。

plyr扩展包中的主要函数可以用****ply来概括:第一个 * 表示输入数据的结构,可选的数据结构有a(array)** 、d(data.frame)l (list) ;第二个 * 表示输出数据的结构,可选的数据结构除了前面3种以外,还有"_",它表示++不输出,它的结果常用于绘图和建立缓存。++

|--------|----------|-----------|------------|---------|
| 输入 | 输出数组 | 输出数据框 | 输出数据列表 | 无输出 |
| 数组 | aaply | adply | alply | a_ply |
| 数据框 | daply | ddply | dlply | d_ply |
| 列表 | laply | ldply | llply | l_ply |
[plyr包的12个主要函数]

按照输入数据的结构可以分为3类:

**a*ply(.data, .margins, .fun, ..., .progress="none"):**按照维度对数组进行"切片";

**d*ply(.data, .variables, .fun, ..., .progress="none"):**按照一列或多列将数据框分为若干子集;

**l*ply(.data, .fun, ..., .progress="none"):**将列表的每个分量作为子集。
参数详解:

.data:表示输入数据;

.margins:表示数组的边际,与apply函数的MARGIN类似,也可以为向量。用来描述输入数据将如何被分割为若干部分;

.variables:表示分组变量,可以有多个变量。用来描述输入数据将如何被分割为若干部分。

.fun:表示应用于数据各部分的函数,如果没有指定.fun,则表示从一种数据结构变为另一种数据结构;

...:表示传递给.fun的其它参数;

.progress:表示进度条的类型,none表示不显示进度条,它有text,tk和win三种进度条。

下面用datasets包中的鸢尾花数据集iris和iris3举例:

R 复制代码
library(plyr)
iris.set <- iris
iris3.set <- iris3
class(iris)
class(iris3)

若不在**.fun**指定应用函数,**ply()函数的作用仅仅是将数据集从一种结构转换为另一种结构。

R 复制代码
iris.set1 <- dlply(iris.set, .variables="Species")
head(iris.set1)

二、dplyr包

plyr 包虽然功能强大,但在处理大数据集时可能会比较慢 。对于更高效的数据处理,可以考虑使用 dplyr 包,它是 plyr 的一个现代替代品,提供了更快的速度和更直观的语法。

dplyr包主要针对数据框和tibble(tbl_df对象,一种增强的数据框)的操作。tibble数据结构在呈现大型数据集时非常友好。

下面以nyflights13扩展包中的flights数据集为例,此数据集中包含了336776次航班信息。(先安装install.packages("nyflights13")。

flights数据集就是一个tibble类型的数据框,它和一般数据框的区别是,当打印到控制台上时会附带上更多的信息。例如,行数和列数,每一列的数据类型,少量的数据示例及省略的行数、列数和列名。

1、select()函数

用于选择需要的变量用在后续的分析上。

R 复制代码
library(dplyr)
# 选择列变量
head(select(flights, year, flight, dest))

如果要从数据中删除一些变量,可以通过在变量前添加负号(-)来实现。另外,在select()函数中还可以使用一些辅助函数来完成对列的匹配操作:starts_with()、ends_with()、contains()、matches()、num_range()、one_of()和everything()等。

选取以"a"为首字母的变量

R 复制代码
library(dplyr)
# 选择以"a"为首字母的变量
head(select(flights, starts_with("a")))

选取包含"lay"的变量

R 复制代码
library(dplyr)
head(select(flights, contains("lay")))

选取最后单词为".time"的变量

R 复制代码
library(dplyr)
head(select(flights, matches(".time")))

2、filter()函数

用于根据条件对数据的列或者记录进行筛选。

R 复制代码
# 选取在7月19日起飞,并且飞行距离大于800的AS或HA航空公司的航班信息
filter(flights, month==7,day==19,distance>800,carrier=="AS"|carrier=="HA")

对比使用with()函数的筛选方法,就会显得使用filter()函数更加简洁清晰。

R 复制代码
with(flights,flights[month==7 & day==19 & distance > 800 & (carrier=="AS"|carrier=="HA"),])

3、arrange()函数

若是依据多列数据 进行排序,只需按列的顺序写进此函数中即可;如果是逆序排,只需在变量前面加负号 或使用rev()函数即可(注意,逆排序中使用负号的情况仅限于数值变量)

R 复制代码
# 依次按month、day、carrier、origin和dest对flights进行排序
head(arrange(flights,-month,-day,carrier,origin,dest))

4、mutate()函数

转换函数,它可以同时修改和增加若干个变量。与R语言中的内置的转换函数transform()相比,它的优势是可在同一段代码中使用刚建立的新变量。

R 复制代码
library(dplyr)
library(nycflights13)
# 计算飞行节约的时间和平均每小时所节约的时间
flights1 <- mutate(flights, gain=arr_delay - dep_delay, gain_per_hour= gain/(air_time/60))
head(flights1$gain)
head(flights1$gain_per_hour)

5、group_by()和summarise()函数

这两个函数往往一起使用,先对数据集进行分组,然后再按组进行汇总。

先按照航空公司进行分组:

R 复制代码
# 先按航空公司进行分组
flights2 <- group_by(flights, carrier)
# 查看分组变量
group_vars(flights2)
# 查看各组的行数
group_size(flights2)

然后对各航空公司数据进行汇总:

R 复制代码
flights3 <- summarise(flights2, dep_delay_mean = mean(dep_delay, na.rm=T),
                                arr_delay_mean = mean(arr_delay, na.rm=T),
                                distance_sd = sd(distance, na.rm=T))
flights3

6、连接函数

inner_join()函数:用于内连接

left_join()函数:用于左连接

right_join()函数:用于右连接

full_join()函数:用于全连接

7、抽样函数

sample_n()函数:随机选出指定个数(样本容量)的样本数;

sample_frac()函数:随机选出指定百分比的样本数。

R 复制代码
sample_n(flights,size=8)

sample_frac(flights,size=0.10)

8、管道函数%>%

此函数可以通过不断地叠加,减少代码量和中间变量,这种写法极大地提高了代码的可读性和可维护性,特别是在进行数据分析和处理数据框(data frames)时。

在叠加过程中,%>%左边的结果将作为右边函数的第一个参数。

dplyr包中的%>%操作符实际上是从magrittr包中借用的,但dplyr作为数据操作的一个核心包,使得这个操作符在数据科学社区中变得非常流行。

R 复制代码
df <- data.frame(
  id = 1:5,
  name = c("Alice", "Bob", "Charlie", "David", "Eva"),
  score = c(85, 90, 95, 88, 92)
)

# 使用%>%管道函数
filtered_sorted_df <- df %>%
  filter(score > 90) %>%  # 过滤出score大于90的行
  arrange(desc(score)) %>%  # 按score降序排列
  select(name, score)  # 选择name和score列

print(filtered_sorted_df)

%>% 管道函数可以与dplyr包中的其他函数(如mutatesummarisegroup_by等)结合使用:

R 复制代码
flights4 <- flights  %>%
  sample_frac(size = 0.1) %>% # 随机抽取10%的样本
  select(one_of("carrier","month","day",
                "dep_delay","arr_delay",
                "air_time","distance")) %>% # 筛选carrier、month、day等几列变量
  mutate(gain = arr_delay - dep_delay,
         gain_per_hour = gain / (air_time / 60)) %>% # 计算飞行节约时间和平均每小时所节约的时间
  group_by(carrier,month) %>% # 按航空公司和月份
  summarise(gain = mean(gain,na.rm = TRUE),distance = mean(distance,na.rm =TRUE)) # 求gain和distance平均值

flights4
相关推荐
studyer_domi38 分钟前
matlab simulink 117-电路故障分析
开发语言·matlab
studyer_domi39 分钟前
matlab simulink 船舶模糊pid控制仿真
开发语言·matlab
天之涯上上1 小时前
JAVA系统中Spring Boot 应用程序的配置文件:application.yml
java·开发语言
我的运维人生1 小时前
Python在数据科学中的高效应用:从数据处理到模型部署的实战指南
开发语言·python·信息可视化·运维开发·技术共享
丁总学Java1 小时前
判断您的Mac当前使用的是Zsh还是Bash:echo $SHELL、echo $0
开发语言·macos·bash
(ღ星辰ღ)2 小时前
java s7接收Byte字节,接收word转16位二进制
java·开发语言
阿猿收手吧!2 小时前
【CPP】C++后端开发面试:深入理解编程中的锁机制
c语言·开发语言·c++·算法·面试·职场和发展
JAVA-XIMU3 小时前
已验证正常,Java输入字符串生成PDF文件
java·开发语言·pdf
日光倾3 小时前
网络计算机的五个组成部分
开发语言·php
CN.LG3 小时前
JAVA异步的UDP 通讯-客户端
java·开发语言·udp