dplyr

数据加载

本文使用R自带的数据集airquality作为示例数据。
数据内容:1973 年 5 月 1 日至 9 月 30 日纽约市的每日空气质量观测数据,共包含 153 条观测记录( 153 天)。
数据结构: 数据框,包含 6 个变量(列),均为数值型。
变量说明: 6 个变量为
① Ozone 臭氧浓度(ppb)
② Solar.R 太阳辐射(兰利)
③ Wind 风速(英里/小时)
④ Temp 温度(华氏度)
⑤ Month 月份(5-9)
⑥ Day 日期(1-31)
如何查看数据结构、变量说明在之前的文章中有涉及,这里不再赘述。

# 加载dplyr包、读取数据
library(dplyr)
data(airquality)

行操作函数

1. 选择行

1.1 filter():按条件筛选行

# 示例1:筛选 Ozone > 30 且 Temp > 90 的行 
airquality %>% 
  filter(Ozone > 30 & Temp > 90) # 返回数据框,数据框中仅含满足条件的行

# 示例2:筛选 Ozone 列不缺失的行
airquality %>% 
  filter(!is.na(Ozone)) # 返回 Ozone 列完整的行,共 116 行 6 列

1.2 distinct():去除重复行

# 示例1:去除所有列数值都相同的重复观测
airquality %>% 
  distinct() # 所有列数值相同的两个观测(行)判定为重复行。保留第一次出现的那一行,删除后续出现的行,返回删除后的数据框

# 示例2:去除 Month 和 Day 两列均相同的观测
airquality %>% 
  distinct(Month, Day) # 即 Month、Day 两列数值都相同则判定为重复行

1.3 slice():按索引选择行

# 示例1:选取第 10 到 15 行
airquality %>% 
  slice(10:15) 

# 示例2:选取第 10、12、15 行
airquality %>% 
  slice(c(10, 12, 15))

1.4 slice_sample():随机抽取行

参数:
n要抽取的行数。
prop要抽取的比例(nprop不能同时使用)。
replace是否进行有放回的抽样(默认为FALSE)。
weight_by按指定列的权重进行抽样。
by用于分组抽样

# 示例1:随机抽取 5 行数据 
set.seed(123)  # 设置随机数种子,保证随机结果可重现。如不设置,每次随机结果不同。
airquality %>% 
  slice_sample(n = 5) # 随机返回一个 5 行的数据框

# 示例2:随机抽取 10% 的数据
airquality %>% 
  slice_sample(prop = 0.1) # 随机返回约 31 行(153 × 20%)的数据框

# 示例3:抽取 5 行,允许重复抽样
airquality %>% 
  slice_sample(n = 5, replace = TRUE) # 返回的数据框可能包含重复行,因为是有放回抽样

# 示例4:温度作为权重抽取 5 行(温度越高的行被抽中的概率越大)
airquality %>% 
  slice_sample(n = 5, weight_by = Temp) 

# 示例5:每个月随机抽取3天
airquality %>% 
  slice_sample(n = 3, by = Month) # 返回15行(5个月 × 每月3天)

1.5 slice_min() / slice_max():按某列最小/最大值选择行

参数: order_by指定根据哪一列的值来选取行。
n指定要选择的行数。
prop指定要选择的行数的比例(nprop不能同时使用)。
with_ties是否保留并列值。如果为TRUE(默认值),则当一列中有多个数值相同,这些相同数值所在的行都会被保留。如果为FALSE,则只保留前n行。

######################## slice_min()示例 ############################# 
# 选择 Temp 数值最小的 3 行
airquality %>% 
  slice_min(order_by = Temp, n = 3) # Temp 最小值 56 仅出现一行,第二小的 57 出现 3 行,因此最终返回 4 行的数据框

# 选择 Temp 数值最小的 3 行,严格保证输出只有 3 行 
airquality %>% 
  slice_min(order_by = Temp, n = 3, with_ties = FALSE)

# 选取 Temp 最低 10% 的行
airquality %>% 
  slice_min(order_by = Temp, prop = 0.1)

######################## slice_max()示例 ############################# 
# 选择 Wind 数值最高的 3 行
airquality %>% 
  slice_max(order_by = Wind, n = 3) 

# 选取 Temp 最高 10% 的行
airquality %>% 
  slice_max(order_by = Temp, prop = 0.1)

1.6 slice_head()/slice_tail():选择前/后 n 行

# slice_head()提取前 3 行数据 
airquality %>% 
  slice_head(n = 3)
# slice_tail()提取后 3 行数据
airquality %>% 
  slice_tail(n = 3)

2. 排序行

arrange():按一行或多行升降序

# 示例1:按 Wind 升序排列
airquality %>% 
  arrange(Wind)

# 示例2:按 Temp 降序排列
airquality %>% 
  arrange(desc(Temp))

# 示例3:按 Temp 降序, Wind 升序排列
airquality %>% 
  arrange(desc(Temp), Wind)

3. 增加行

add_row():向数据框添加新的行

# 在数据集末尾添加一行
airquality %>%
  add_row(Ozone = 45, Solar.R = 220, Wind = 8.5, Temp = 75, Month = 10, Day = 1)

# 添加多行
airquality %>%
  add_row(Ozone = 45, Solar.R = 220, Wind = 8.5, Temp = 75, Month = 10, Day = 1) %>%
  add_row(Ozone = 38, Solar.R = 190, Wind = 7.2, Temp = 72, Month = 10, Day = 2) %>%
  add_row(Ozone = NA, Solar.R = 210, Wind = 9.1, Temp = 68, Month = 10, Day = 3)

列操作

1.选择列

1.1 pull():提取单列为向量

# 示例:提取 Temperature 列,返回向量
airquality %>% 
  pull(Temp)

1.2 select():选择特定列(单列或多列)

# 示例:选择Temp、Wind和Month三列,返回数据框
airquality %>% 
  select(Temp, Wind, Month)

1.3 relocate():调整列位置

# 示例一:将 Temp 和 Wind 列移到最前面
airquality %>% 
  relocate(Temp, Wind) 
# 示例二:将 Temp 和 Wind 列移到最后面
airquality %>% 
  relocate(Temp, Wind, .after = last_col())
# 在知道最后一列为 Day 的情况下,示例二代码还可以写为:
airquality %>% 
  relocate(Temp, Wind, .after = Day) 

2.添加和命名新列

2.1 mutate():添加新列(默认新列添加到数据框的最后)

用示例数据演示如何新增两列:
a. 将Temp列的温度数据分为低、中、高三个类别,储存在新列temp_category中;
b. 将Wind列数据进行标准化,储存在新列wind_scaled中。

# mutate()函数添加新列
airquality %>% 
  mutate(
    temp_category = case_when(
      Temp < 70 ~ "低温",  # Temp < 70 为低温
      Temp < 85 ~ "中温",  # Temp ≥ 70 且 Temp < 85 为中温
      TRUE ~ "高温"        # 不满足以上为高温
    ), 
    wind_scaled = scale(Wind) #  scale()函数进行标准化
  ) 

cheatsheet中还提到了另一个添加新列的函数:add_column()。与mutate()的区别主要在于,add_column()添加的新列与已有列通常无依赖关系,如添加常量或外部向量。另外,add_column()实际在tribble包中。

2.2

3.多列汇总

这组函数常与summarize()mutate()等函数一起使用

3.1 across():对多列应用相同的函数

# 示例一:计算Temp、Wind两列的均值,均值汇总为两列一行的数据框
airquality %>% 
  select(Temp, Wind, Month)
airquality %>% summarize(across(c(Temp,Wind), mean))

# 示例二:计算所有列的均值
airquality %>% 
  select(Temp, Wind, Month)
airquality %>% summarize(across(everything(), mean)) 

3.2 c_across():跨列组合

rowwise() 模式下跨多列进行计算

# 示例一:在数据最后增加一列,该列为每行中各个列的数值之和
airquality %>% 
  rowwise() %>% 
  mutate(
    numeric_sum = sum(c_across(where(is.numeric)), na.rm = TRUE)
  )