R语言数据科学:dplyr与tidyr数据整理完全指南

R语言数据科学:dplyr与tidyr数据整理完全指南

【免费下载链接】cheatsheets-ai kailashahirwar/cheatsheets-ai: 是一个包含各种人工智能和机器学习领域速查表的 GitHub 仓库,包括机器学习算法、深度学习方法、神经网络等。适合用于快速查找和参考人工智能和机器学习领域的信息,尤其是对于需要快速掌握和回顾某个 AI 和机器学习概念的开发人员。 【免费下载链接】cheatsheets-ai 项目地址: https://gitcode.com/gh_mirrors/ch/cheatsheets-ai

本文全面介绍了R语言中dplyr和tidyr这两个核心数据整理包的高级用法和最佳实践。dplyr部分详细讲解了filter()数据筛选、select()列选择、arrange()数据排序、mutate()创建新变量以及group_by()与summarize()分组汇总等核心函数,并涵盖了窗口函数、数据连接操作和性能优化技巧。tidyr部分深入探讨了pivot_longer()和pivot_wider()数据透视、复杂的分列与合并操作、缺失值处理、嵌套数据处理以及正则表达式的高级应用。文章还提供了R Studio数据科学工作流的构建方法,包括模块化设计、管道操作、错误处理和性能优化策略,最后对比分析了R与Python工具链的差异并提供了协作集成方案。

dplyr数据转换与操作核心函数

dplyr是R语言中最强大的数据操作包之一,提供了简洁直观的语法来处理数据框。它基于"动词"的概念,每个函数都执行特定的数据操作任务,让数据转换变得直观且高效。

核心数据操作函数

1. 数据筛选:filter()

filter()函数用于基于条件筛选行数据,类似于SQL中的WHERE子句。它支持多种逻辑运算符和条件组合。

# 基本筛选示例
library(dplyr)
library(nycflights13)

# 筛选1月1日的航班
jan1_flights <- filter(flights, month == 1, day == 1)

# 使用逻辑运算符
long_flights <- filter(flights, dep_delay > 60 | arr_delay > 60)
short_flights <- filter(flights, air_time < 60 & distance < 200)

# 使用between()函数
medium_flights <- filter(flights, between(air_time, 60, 180))
2. 列选择:select()

select()函数用于选择、重命名和重新排序列,支持多种选择辅助函数。

# 选择特定列
flight_info <- select(flights, year, month, day, carrier, flight)

# 使用选择辅助函数
time_columns <- select(flights, starts_with("dep"), starts_with("arr"))
numeric_cols <- select(flights, where(is.numeric))

# 重命名列
renamed_flights <- select(flights, 
                         airline = carrier, 
                         flight_number = flight,
                         departure_time = dep_time)

# 排除列
without_time <- select(flights, -c(dep_time, arr_time, sched_dep_time))
3. 数据排序:arrange()

arrange()函数用于对数据框按指定列进行排序,支持升序和降序排列。

# 基本排序
sorted_by_departure <- arrange(flights, dep_delay)

# 降序排列
most_delayed <- arrange(flights, desc(dep_delay))

# 多列排序
complex_sort <- arrange(flights, desc(dep_delay), carrier, flight)

# 处理缺失值(默认放在最后)
sorted_with_na <- arrange(flights, dep_delay, .na_last = FALSE)
4. 创建新变量:mutate()

mutate()函数用于创建新的列或修改现有列,支持向量化操作。

# 创建新列
flights_with_speed <- mutate(flights,
                           speed_mph = distance / (air_time / 60),
                           is_delayed = dep_delay > 0)

# 使用case_when进行条件转换
flights_categorized <- mutate(flights,
                            delay_category = case_when(
                              dep_delay <= 0 ~ "On Time",
                              dep_delay <= 15 ~ "Slight Delay",
                              dep_delay <= 60 ~ "Moderate Delay",
                              TRUE ~ "Severe Delay"
                            ))

# 使用across()进行多列操作
flights_normalized <- mutate(flights,
                           across(c(dep_delay, arr_delay), 
                                  ~ (. - mean(., na.rm = TRUE)) / sd(., na.rm = TRUE)))
5. 分组汇总:group_by() + summarize()

group_by()和summarize()组合用于分组计算汇总统计量。

# 基本分组汇总
carrier_stats <- flights %>%
  group_by(carrier) %>%
  summarize(
    avg_dep_delay = mean(dep_delay, na.rm = TRUE),
    avg_arr_delay = mean(arr_delay, na.rm = TRUE),
    total_flights = n(),
    on_time_percentage = mean(dep_delay <= 0, na.rm = TRUE) * 100
  )

# 多级分组
monthly_stats <- flights %>%
  group_by(year, month, carrier) %>%
  summarize(
    flights_count = n(),
    avg_delay = mean(dep_delay, na.rm = TRUE),
    .groups = 'drop'
  )

# 使用across()进行多列汇总
numeric_summary <- flights %>%
  group_by(carrier) %>%
  summarize(across(where(is.numeric), 
                   list(mean = ~mean(., na.rm = TRUE), 
                        sd = ~sd(., na.rm = TRUE))))

高级数据操作技巧

窗口函数

dplyr提供了一系列窗口函数用于在分组内进行计算:

# 排名函数
ranked_flights <- flights %>%
  group_by(carrier) %>%
  mutate(
    delay_rank = min_rank(desc(dep_delay)),
    delay_percent_rank = percent_rank(dep_delay)
  ) %>%
  filter(delay_rank <= 3)

# 滑动窗口计算
rolling_stats <- flights %>%
  group_by(carrier) %>%
  arrange(year, month, day) %>%
  mutate(
    avg_delay_7d = zoo::rollmean(dep_delay, 7, na.rm = TRUE, fill = NA),
    total_flights_30d = zoo::rollsum(!is.na(dep_delay), 30, fill = NA)
  )
数据连接操作

dplyr支持多种SQL风格的连接操作:

# 内连接
flights_with_planes <- inner_join(flights, planes, by = "tailnum")

# 左连接
flights_with_airlines <- left_join(flights, airlines, by = "carrier")

# 全连接
complete_data <- full_join(flights, weather, by = c("year", "month", "day", "hour"))

# 反连接(查找不匹配的记录)
missing_planes <- anti_join(flights, planes, by = "tailnum")

性能优化技巧

# 使用data.table后端提高性能
library(dtplyr)
flights_dt <- lazy_dt(flights)
fast_operations <- flights_dt %>%
  filter(dep_delay > 0) %>%
  group_by(carrier) %>%
  summarize(avg_delay = mean(dep_delay)) %>%
  as_tibble()

# 使用collapse包进行高速操作
library(collapse)
fast_summary <- flights %>%
  fgroup_by(carrier) %>%
  fsummarise(avg_delay = fmean(dep_delay, na.rm = TRUE))

# 内存优化
optimized_flights <- flights %>%
  select(where(~!all(is.na(.)))) %>%  # 移除全NA列
  mutate(across(where(is.character), as.factor))  # 字符列转为因子

错误处理和调试

# 安全的数据操作
safe_mutate <- safely(mutate)
result <- safe_mutate(flights, new_col = non_existent_column * 2)

if (!is.null(result$error)) {
  warning("Mutation failed: ", result$error$message)
  # 执行备用操作
}

# 调试管道操作
debug_pipeline <- flights %>%
  { cat("Initial rows:", nrow(.), "\n"); . } %>%
  filter(dep_delay > 0) %>%
  { cat("After filter:", nrow(.), "\n"); . } %>%
  group_by(carrier) %>%
  { cat("Groups:", n_groups(.), "\n"); . }

dplyr的这些核心函数构成了R语言数据操作的基础,通过管道操作符(%>%)将它们连接起来,可以构建出强大而优雅的数据处理流程。掌握这些函数的使用方法和最佳实践,将极大地提高数据分析和处理的效率。

tidyr数据整理与重塑高级技巧

在数据科学工作流中,数据整理往往占据着70%以上的时间。tidyr作为tidyverse生态系统中的核心包,专门负责数据的整理和重塑工作。掌握tidyr的高级技巧能够显著提升数据处理效率,让数据分析工作更加流畅。

数据透视:长宽格式转换的艺术

数据透视是tidyr最核心的功能之一,主要涉及pivot_longer()pivot_wider()两个函数。理解这两种转换的适用场景至关重要。

宽表转长表:pivot_longer()

当列名实际上代表某个变量的值时,需要使用pivot_longer()将宽表转换为长表。这种转换增加了行数,减少了列数。

# 示例:宽表转长表
library(tidyr)
library(dplyr)

# 原始宽格式数据
sales_wide <- tibble(
  product = c("A", "B", "C"),
  Q1_2023 = c(100, 150, 200),
  Q2_2023 = c(120, 160, 210),
  Q1_2024 = c(110, 170, 220)
)

# 转换为长格式
sales_long <- sales_wide %>%
  pivot_longer(
    cols = -product,  # 除product外的所有列
    names_to = "quarter_year", 
    values_to = "sales"
  )

print(sales_long)

mermaid

长表转宽表:pivot_wider()

当观测值分散在多个行中时,需要使用pivot_wider()将长表转换为宽表。这种转换减少了行数,增加了列数。

# 示例:长表转宽表
# 假设我们有长格式的学生成绩数据
grades_long <- tibble(
  student = rep(c("Alice", "Bob", "Charlie"), each = 3),
  subject = rep(c("Math", "Science", "English"), times = 3),
  score = c(90, 85, 88, 78, 92, 84, 95, 87, 91)
)

# 转换为宽格式
grades_wide <- grades_long %>%
  pivot_wider(
    names_from = subject,
    values_from = score
  )

print(grades_wide)

复杂的分列与合并操作

高级分列技巧

separate()函数不仅可以用分隔符分列,还支持正则表达式和位置分列。

# 使用正则表达式进行复杂分列
complex_data <- tibble(
  id = 1:3,
  info = c("John_Doe_30_M", "Jane_Smith_25_F", "Bob_Johnson_35_M")
)

# 使用正则表达式分列
separated_data <- complex_data %>%
  separate(
    info,
    into = c("first_name", "last_name", "age", "gender"),
    sep = "_",
    convert = TRUE  # 自动转换数据类型
  )

# 使用位置分列
date_data <- tibble(
  datetime = c("202301151430", "202302161545", "202303171600")
)

position_separated <- date_data %>%
  separate(
    datetime,
    into = c("date", "time"),
    sep = 8  # 在第8个字符后分割
  ) %>%
  separate(
    date,
    into = c("year", "month", "day"),
    sep = c(4, 6)  # 在第4和第6个字符后分割
  )
智能合并列

unite()函数可以灵活地合并多个列,并控制分隔符的使用。

# 创建示例数据
person_data <- tibble(
  first_name = c("John", "Jane", "Bob"),
  last_name = c("Doe", "Smith", "Johnson"),
  age = c(30, 25, 35),
  city = c("New York", "London", "Tokyo")
)

# 合并姓名,使用空格分隔
full_names <- person_data %>%
  unite("full_name", first_name, last_name, sep = " ")

# 创建复杂的标识符
complex_id <- person_data %>%
  unite("person_id", first_name, age, city, sep = "-", remove = FALSE)

处理缺失值与数据补全

tidyr提供了强大的工具来处理数据中的缺失值问题。

显式化缺失值
# 创建包含隐式缺失值的数据
incomplete_data <- tibble(
  group = c("A", "A", "B", "B"),
  time = c(1, 3, 1, 2),
  value = c(10, 30, 20, 40)
)

# 使用complete显式化所有可能的组合
complete_data <- incomplete_data %>%
  complete(group, time = 1:3)

# 使用fill填充缺失值
filled_data <- complete_data %>%
  group_by(group) %>%
  fill(value, .direction = "downup")
替换缺失值
# 创建包含NA的数据
data_with_na <- tibble(
  x = c(1, 2, NA, 4, NA),
  y = c("a", NA, "c", "d", "e")
)

# 替换特定值
replaced_data <- data_with_na %>%
  replace_na(list(x = 0, y = "unknown"))

# 使用前后值填充
filled_na <- data_with_na %>%
  fill(x, y, .direction = "down")

嵌套数据处理

对于复杂的分层数据结构,tidyr提供了强大的嵌套功能。

# 创建嵌套数据
nested_data <- tibble(
  department = c("Sales", "IT", "HR"),
  employee_data = list(
    tibble(name = c("John", "Jane"), salary = c(50000, 60000)),
    tibble(name = c("Bob", "Alice"), salary = c(70000, 80000)),
    tibble(name = c("Charlie", "Diana"), salary = c(55000, 65000))
  )
)

# 展开嵌套数据
unnested_data <- nested_data %>%
  unnest(employee_data)

# 重新嵌套数据
renested_data <- unnested_data %>%
  nest(employee_data = c(name, salary))

正则表达式的高级应用

tidyr的separate_wider_regex()函数提供了基于正则表达式的强大分列能力。

# 复杂字符串解析
complex_strings <- tibble(
  data = c(
    "ProductA-2023Q1-USD1500",
    "ProductB-2023Q2-EUR2000", 
    "ProductC-2023Q3-GBP1800"
  )
)

# 使用正则表达式分列
parsed_data <- complex_strings %>%
  separate_wider_regex(
    data,
    patterns = c(
      product = "^[A-Za-z]+",
      "-",
      quarter = "\\d{4}Q[1-4]",
      "-",
      currency = "[A-Z]{3}",
      amount = "\\d+"
    )
  )

性能优化技巧

处理大型数据集时,性能优化至关重要。

# 使用data.table后端提高性能
library(dtplyr)

# 将数据转换为data.table
large_data <- as.data.table(large_dataset)

# 使用dtplyr进行高效操作
result <- large_data %>%
  lazy_dt() %>%
  pivot_longer(
    cols = starts_with("value"),
    names_to = "metric",
    values_to = "score"
  ) %>%
  group_by(category, metric) %>%
  summarise(avg_score = mean(score, na.rm = TRUE)) %>%
  as_tibble()

错误处理与调试

在实际应用中,健壮的错误处理是必不可少的。

# 安全的pivot操作
safe_pivot <- function(data, cols, names_to, values_to) {
  tryCatch({
    result <- data %>%
      pivot_longer(
        cols = all_of(cols),
        names_to = names_to,
        values_to = values_to
      )
    return(result)
  }, error = function(e) {
    message("Pivot操作失败: ", e$message)
    # 返回原始数据或执行备用方案
    return(data)
  })
}

# 使用安全函数
safe_result <- safe_pivot(
  data = my_data,
  cols = c("col1", "col2", "col3"),
  names_to = "variable",
  values_to = "value"
)

通过掌握这些高级技巧,你能够处理各种复杂的数据整理场景,从简单的格式转换到复杂的嵌套数据处理,都能够游刃有余。记住,良好的数据整理是成功数据分析的基础,投资时间学习这些技巧将在长期项目中带来巨大的回报。

R Studio数据科学工作流构建

在现代数据科学实践中,R Studio作为R语言的核心集成开发环境,为数据科学家提供了强大的工作流构建能力。通过结合dplyr和tidyr这两个tidyverse生态系统中的核心包,我们可以构建出高效、可重复且易于维护的数据科学工作流。

工作流架构设计

一个完整的R Studio数据科学工作流通常包含以下核心组件:

flowchart TD
    A[数据导入<br>readr::read_csv]

【免费下载链接】cheatsheets-ai kailashahirwar/cheatsheets-ai: 是一个包含各种人工智能和机器学习领域速查表的 GitHub 仓库,包括机器学习算法、深度学习方法、神经网络等。适合用于快速查找和参考人工智能和机器学习领域的信息,尤其是对于需要快速掌握和回顾某个 AI 和机器学习概念的开发人员。 【免费下载链接】cheatsheets-ai 项目地址: https://gitcode.com/gh_mirrors/ch/cheatsheets-ai

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值