R语言中的宽长数据转换:tidyr包的使用指南

news2024/9/30 3:21:07

在数据分析中,数据的存储方式直接影响分析过程的效率和准确性。常见的数据存储形式有宽型数据(wide format)和长型数据(long format)。宽型数据适合人类查看和理解,而长型数据则更适合计算机处理和分析。为此,R语言提供了tidyr包,用于在这两种数据格式之间进行转换。本指南将详细介绍tidyr包中最常用的两个函数:gather()spread(),并结合实际案例进行讲解。

一、什么是宽型数据和长型数据?

宽型数据(Wide Format Data)

宽格式数据集中,每一行代表一个独特的实体(如一个病人),每一列代表不同的变量或属性。所有的变量都以列的形式展开,数据在水平方向上延展。例如,一个包含病人血压、血糖和胆固醇水平的数据集可能如下所示:

病人ID血压血糖胆固醇
00112090200
00213085180
00312588210

长型数据(Long Format Data

在长格式数据集中,同一个实体可以在多行中出现,每一行包含一个特定的观察值或测量值。通常有两个主要的列,一个表示变量名称,另一个表示变量值。例如,上述数据集的长格式可能如下所示:

病人ID变量
001血压120
001血糖90
001胆固醇200
002血压130
002血糖85
002胆固醇180

二、为什么临床原始数据多是长格式?

1、纵向研究

纵向研究是指在不同时间点对同一组个体进行重复测量的研究设计。长格式数据结构能够更清晰地记录每个时间点的测量值,使得数据管理和分析更加方便。例如,在一项关于糖尿病患者血糖水平的纵向研究中,数据可以这样存储:

ID时间点血糖水平
001T16
001T26.5
001T36.8

2、重复测量

在临床试验中,通常会对同一个体在不同条件下进行多次测量。长格式数据结构可以很好地记录这些重复测量,方便数据的处理和分析。例如,一项关于药物效果的研究可能会记录每个患者在不同剂量下的反应:

ID剂量反应值
001低剂量5
001中剂量7
001高剂量9

这种格式便于进行统计分析,如方差分析(ANOVA)和混合效应模型。

3、数据扩展性

长格式数据便于扩展新的变量或观察值,而无需重新设计数据结构。例如,在一项长期的临床随访研究中,研究人员可以随时添加新的随访时间点或新的测量指标,而不需要改变现有数据结构:

ID时间点血压血糖值胆固醇
001T112062
001T212551.8

4、数据整合和处理

长格式数据更便于与其他数据源进行整合和处理。例如,在进行多中心临床研究时,不同中心的数据可以方便地合并到一个长格式的数据集中:

三、安装和加载tidyr包

tidyr是R语言中用于数据清理和重塑的重要工具,其主要目的是帮助用户创建“整洁数据”(tidy data)。在整洁数据中,每一个变量占用一列,每一条观察值占用一行,每个单元格包含一个单一的值。tidyr提供了丰富的工具来改变数据的形状(即数据的pivoting)和层次结构(即嵌套和解嵌套)。

在开始之前,确保已经安装并加载了tidyr包。可以使用以下命令进行安装和加载:

install.packages("tidyr")

library(tidyr)

1、创建示例数据

我们首先创建一个简单的宽型数据框datapati,该数据框包含三个变量(xyz)和一个时间变量time

library(tibble)
datapati <- tibble(time = as.Date('2025-01-01') + 1:3, x = c(1, 2, 3), y = c(8, 5, 6), z = c(3, 0, 3))
print(datapati)

结果是:

# A tibble: 3 × 4
  time           x     y     z
  <date>     <dbl> <dbl> <dbl>
1 2025-01-02     1     8     3
2 2025-01-03     2     5     0
3 2025-01-04     3     6     3

2、gather()函数

gather()函数是tidyr包中的一个重要工具,用于将宽型数据转换为长型数据。

gather(data, key = "key", value = "value", ..., na.rm = FALSE, convert = FALSE, factor_key = FALSE)

data:要转换的数据框。这个参数指定了需要进行宽转长操作的数据集。

key:新数据框中存放原宽数据中需转列为行的原变量名称。这一列将在转换后包含原数据框中的列名。

value:新数据框中存放原宽数据中需转换列的某行具体数值。这一列将在转换后包含原数据框中对应列的数值。

...:需要转换的列。如果不设置,默认是全部转换。通过指定这些列,可以控制哪些列需要进行宽转长转换。

示例代码:

datapati_long <- gather(data = datapati, key = "patients", value = "measurement", -time)
print(datapati_long)

在这个示例中,gather()函数将xyz列转换为长型格式,新的数据框datapati_long中包含三个变量:timepatientsmeasurement

  time       patients measurement
  <date>     <chr>          <dbl>
1 2025-01-02 x                  1
2 2025-01-03 x                  2
3 2025-01-04 x                  3
4 2025-01-02 y                  8
5 2025-01-03 y                  5
6 2025-01-04 y                  6
7 2025-01-02 z                  3
8 2025-01-03 z                  0
9 2025-01-04 z                  3

3、spread()函数

spread()函数用于将长型数据转换为宽型数据。

spread(data, key, value, fill = NA, convert = FALSE, drop = TRUE, sep = NULL)

我们先创建一个新的长型数据框datapati2

datapati2 <- data.frame(x = c("a", "b", "c"), y = c(3, 4, 5))
print(datapati2)

结果是:

  x y
1 a 3
2 b 4
3 c 5

使用spread()函数将其转换为宽型数据:

datapati_wide <- spread(datapati2, key = x, value = y) 
print(datapati_wide)

结果是:

  a b c
1 3 4 5

更复杂的示例

考虑一个更复杂的情境,我们有一个包含多个变量的数据框:

library(tibble)
data_complex <- tibble(
  id = 1:3,
  age = c(23, 45, 31),
  income = c(50000, 60000, 55000),
  height = c(175, 160, 180),
  weight = c(70, 80, 75)
)
print(data_complex)

结果是:

# A tibble: 3 × 5
     id   age income height weight
  <int> <dbl>  <dbl>  <dbl>  <dbl>
1     1    23  50000    175     70
2     2    45  60000    160     80
3     3    31  55000    180     75

将其转换为长型数据:

data_complex_long <- gather(data_complex, key = "variable", value = "value", -id)
print(data_complex_long)

结果是:

# A tibble: 12 × 3
      id variable value
   <int> <chr>    <dbl>
 1     1 age         23
 2     2 age         45
 3     3 age         31
 4     1 income   50000
 5     2 income   60000
 6     3 income   55000
 7     1 height     175
 8     2 height     160
 9     3 height     180
10     1 weight      70
11     2 weight      80
12     3 weight      75

将长型数据转换回宽型数据:

data_complex_wide <- spread(data_complex_long, key = variable, value = value)
print(data_complex_wide)

结果是:

# A tibble: 3 × 5
     id   age height income weight
  <int> <dbl>  <dbl>  <dbl>  <dbl>
1     1    23    175  50000     70
2     2    45    160  60000     80
3     3    31    180  55000     75

4、tidyr中的其他函数

除了 gather() 和 spread() 等函数外,tidyr 包还提供了许多其他有用的函数来处理数据格式转换。

例如,pivot_longer() 函数能够将数据从宽型转换为长型,它其实是 gather() 的升级版,在功能和灵活性上有所增强。还有 pivot_wider() 函数,它负责将数据从长型转换为宽型,是 spread() 的升级版。此外,separate() 函数可以将一个列拆分为多个列,比如原本一个包含日期和时间的列,可以通过它拆分为日期列和时间列。而 unite() 函数的作用则相反,能够将多个列合并为一个列,比如把姓名的姓和名两个列合并为一个完整姓名列。这些函数为数据的整理和转换提供了丰富的工具和便捷的操作方式。

使用pivot_longer()

pivot_longer()函数可以替代gather(),提供了更多的灵活性和功能:

datapati_longer <- pivot_longer(datapati, cols = -time, names_to = "patients", values_to = "measurement")
print(datapati_longer)

结果是:

# A tibble: 9 × 3
  time       patients measurement
  <date>     <chr>          <dbl>
1 2025-01-02 x                  1
2 2025-01-02 y                  8
3 2025-01-02 z                  3
4 2025-01-03 x                  2
5 2025-01-03 y                  5
6 2025-01-03 z                  0
7 2025-01-04 x                  3
8 2025-01-04 y                  6
9 2025-01-04 z                  3

使用pivot_wider()

pivot_wider()函数可以替代spread()

datapati_wider <- pivot_wider(datapati_longer, names_from = patients, values_from = measurement)
print(datapati_wider)

结果是:

# A tibble: 3 × 4
  time           x     y     z
  <date>     <dbl> <dbl> <dbl>
1 2025-01-02     1     8     3
2 2025-01-03     2     5     0
3 2025-01-04     3     6     3

5、实际案例分析

为了更好地理解tidyr包的实际应用,我们来看看一个真实案例。假设我们有一个关于不同地区气温变化的数据集,我们需要将其从宽型数据转换为长型数据,以便进行进一步的分析和绘图。

创建数据集

temperature_data <- tibble(
  region = c("North", "South", "East", "West"),
  Jan = c(32, 45, 50, 40),
  Feb = c(35, 48, 53, 42),
  Mar = c(40, 50, 60, 50)
)
print(temperature_data)

结果是:

# A tibble: 4 × 4
  region   Jan   Feb   Mar
  <chr>  <dbl> <dbl> <dbl>
1 North     32    35    40
2 South     45    48    50
3 East      50    53    60
4 West      40    42    50

转换为长型数据

temperature_long <- pivot_longer(temperature_data, cols = -region, names_to = "month", values_to = "temperature")
print(temperature_long)

结果是:

   region month temperature
   <chr>  <chr>       <dbl>
 1 North  Jan            32
 2 North  Feb            35
 3 North  Mar            40
 4 South  Jan            45
 5 South  Feb            48
 6 South  Mar            50
 7 East   Jan            50
 8 East   Feb            53
 9 East   Mar            60
10 West   Jan            40
11 West   Feb            42
12 West   Mar            50

6、可视化数据分析

下一步,我们可以利用长型数据进行可视化分析。比如,用基本的R绘图库(base绘图)来绘制各地区每月的平均气温变化:

# 提取不同区域的数据
regions <- unique(temperature_long$region)
months <- unique(temperature_long$month)
colors <- c("red", "green", "blue", "purple")

# 创建空的绘图区域
plot(1, type = "n", xlab = "Month", ylab = "Temperature (°F)", 
     xlim = c(1, length(months)), ylim = range(temperature_long$temperature),
     xaxt = "n", main = "Monthly Temperature Changes by Region")

# 设置x轴标签
axis(1, at = 1:length(months), labels = months)

# 绘制每个区域的线和点
for (i in 1:length(regions)) {
  region_data <- subset(temperature_long, region == regions[i])
  lines(1:length(months), region_data$temperature, type = "o", col = colors[i], pch = 16)
}

# 添加图例
legend("topright", legend = regions, col = colors, pch = 16, lty = 1)

结果是:

2702bc4582bb41aa9c8d7f0b799eea34.png

也可以利用ggplot2包,它是R语言中一个功能强大且灵活的数据可视化工具。由Hadley Wickham开发并基于“Grammar of Graphics”理念,ggplot2包使用户能够创建复杂且美观的图形,广泛应用于数据分析和可视化领域。

library(ggplot2)

ggplot(temperature_long, aes(x = month, y = temperature, color = region, group = region)) +
  geom_line() +
  geom_point() +
  labs(title = "Monthly Temperature Changes by Region",
       x = "Month",
       y = "Temperature (°F)") +
  theme_minimal()

结果是:

44374d7ec11c4139a05e1d5214ac8bac.png

通过本文的讲解,我们详细介绍了R语言中tidyr包用于宽长数据转换的基本方法。理解和掌握这些方法对于数据科学家和分析师在数据预处理和分析过程中是至关重要的。gather()spread()函数,及其升级版pivot_longer()pivot_wider(),提供了强大的功能,可以简化数据格式转换,提高数据分析的效率和准确性。在实际工作中,合理利用这些工具,可以极大地优化数据处理流程,提升分析质量。

adce135f307b4c9f80f5e69cb20c8bb0.png

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1980145.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI生成PPT?三款工具让总结更轻松

哎呀&#xff0c;职场新人们&#xff0c;你们是不是也跟我一样&#xff0c;刚开始做PPT的时候&#xff0c;感觉像是走进了一个大迷宫&#xff0c;脑袋里装满了想法&#xff0c;但就是不知道怎么把它们变成一页页漂亮的幻灯片&#xff1f;别急&#xff0c;今天咱们就来聊聊三个超…

JavaEE-多线程编程阻塞队列

目录 生产者消费者模型 生产者消费者模型优势 通过代码看一下生产者消费者模型&#xff08;使用阻塞队列&#xff09; 自己实现阻塞队列 之前在数据结构中学的队列是最基础的队列&#xff0c;在实际开发中针对队列还有很多形式&#xff1a;&#xff08;1&#xff09;普通队…

PyCharm | PyCharm中创建带有注释的py文件

文章目录 0 问题引入1 问题解决1.1 在Pycharm里进行设置1.2 模板1.3 可选参数 2 效果展示 0 问题引入 想要创建带注释的py文件&#xff0c;该如何解决呢&#xff1f; 1 问题解决 1.1 在Pycharm里进行设置 打开Pycharm的Seetings按照如图所示来操作 1.2 模板 # -*- codin…

【大模型从入门到精通3】openAI api的入门介绍3

这里写目录标题 理论问题实践问题任务 1: 基本的 API 请求任务 2: 安全处理 API 密钥任务 3: 解释 API 响应任务 4: 强大的错误处理任务 5: 交互式聊天界面任务 6: 响应后处理任务 7: 动态内容生成任务 8: 优化与监控 理论问题 整合OpenAI的API到应用中为机器学习工程师、数据…

python运行js之execjs基本使用

python运行js之execjs基本使用 现在大部分网站都使用JS加密和JS加载的情况&#xff0c;数据并不能直接被抓取出来&#xff0c;这时候就需要使用第三方类库来执行JS语句。 官网&#xff1a;https://pypi.org/project/PyExecJS/ 使用前提&#xff1a;电脑需要安装 Node.js 一、安…

20240805 每日AI必读资讯

世界首例&#xff01;AI机器人做牙科手术&#xff0c;8倍速诊疗比人类医生更精准 - Perceptive&#xff1a;让人工智能控制的自主机器人&#xff0c;首次对人类患者进行了全过程的牙科手术&#xff0c;速度大约是人类牙医的8倍。 - 两项新技术 1、OCT 3D成像系统&#xff1a;…

【MySQL进阶】MySQL主从复制

目录 MySQL主从复制 概念 主从形式 一主多从 多主一从 双主复制 主从级联复制 主从复制原理 三个线程 两个日志文件 主从复制的主要工作模式 异步复制 半同步复制 全同步复制 MySQL主从复制 概念 MySQL主从复制是一种数据分布机制&#xff0c;允许从一个数据库服…

Chapter 26 Python魔术方法

欢迎大家订阅【Python从入门到精通】专栏&#xff0c;一起探索Python的无限可能&#xff01; 文章目录 前言一、什么是魔术方法&#xff1f;二、常见的魔术方法① __init__构造方法② __str__字符串方法③ __lt__比较方法④ __le__比较方法⑤ __eq__比较方法 前言 本章将详细讲…

RabbitMQ高级特性 - 消费者消息确认机制

文章目录 RabbitMQ 消息确认机制背景消费者消息确认机制概述手动确认&#xff08;RabbitMQ 原生 SDK&#xff09;手动确认&#xff08;Spring-AMQP 封装 RabbitMQ SDK&#xff09;AcknowledgeMode.NONEAcknowledgeMode.AUTO&#xff08;默认&#xff09;AcknowledgeMode.MANUAL…

思源笔记软件的优缺点分析

在过去一年里&#xff0c;我用了很多款笔记&#xff0c;从word文档到onenote到语雀再到思源&#xff0c;最后坚定的选择了思源笔记 使用感受 首先是用word文档来记笔记&#xff0c;主要是开始时不知道笔记软件怎么好用&#xff0c;等到笔记越来越膨胀的时候我发现&#xff0c…

2024死磕小红书,一定能赚到钱!

​2024死磕小红书&#xff0c;一定能赚到钱&#xff01;在文末领取小红书运营完全指南电子书 从2023年起&#xff0c;小红书这股热乎劲儿就像开了挂&#xff0c;突然间就成了人人想蹭的“显学”。大伙儿都想趁着平台红利期&#xff0c;分一杯羹。说来惭愧&#xff0c;我从2020年…

C语言指针·高级用法超详解(指针运算、野指针、悬空指针、void类型指针、二级以及多级指针)

目录 1. 指针的运算 2. 野指针和悬空指针 2.1 野指针 2.2 悬空指针 3. void类型指针 4. 二级指针和多级指针 4.1 命名规则 4.2 作用 4.2.1 二级指针可以操作一级指针记录的地址 4.2.2 利用二级指针获取变量中记录的数据 1. 指针的运算 文章开始前可以先了…

基于强化学习的Deep-Qlearning网络玩cartpole游戏

1、环境准备&#xff0c;gym的版本为0.26.2 2、编写网络代码 # 导入必要的库 import gym import torch import torch.nn as nn import torch.optim as optim import numpy as np from collections import deque import random# 定义DQN网络 class DQN(nn.Module):def __init__…

《深入浅出WPF》学习笔记五.Mvvm设计模式

《深入浅出WPF》学习笔记五.Mvvm设计模式 背景 在通过视频学习wpf的过程中&#xff0c;讲师花了不少篇幅来讲Mvvm。特地在此用自己的语言总结一番,方便以后面试回答&#xff0c;如有理解不对&#xff0c;欢迎指正哈。 Mvvm结构 Mvvm指的是ModelViewViewModel 为什么要使用…

《网络安全自学教程》- MySQL匿名用户的原理分析与实战研究

《网络安全自学教程》 低版本的MySQL数据库在安装时会创建一个用户名和密码为空的账户&#xff0c;也就是匿名账户。即使升级到高版本&#xff0c;匿名账户仍然会存在。 MySQL匿名账户 1、检查是否存在匿名账户2、检查用户权限3、创建匿名账户4、使用匿名账户登录5、删除匿名账…

医院管理系统

医院管理系统 本文所涉及所有资源均在传知代码平台可获取 文章目录 医院管理系统概述使用技术核心功能1. 登录与注册2. 管理员系统3. 患者系统&#xff08;医院电子平台&#xff09;4. 医生系统&#xff08;坐诊系统&#xff09; 部署与启动适用场景 概述 本项目是一个专为大学…

读零信任网络:在不可信网络中构建安全系统09用户信任

1. 用户信任 1.1. 将设备身份和用户身份混为一谈会导致一些显而易见的问题 1.1.1. 特别是当用户拥有多台设备时&#xff0c;而这种情况很普遍 1.1.2. 应该针对不同类型的设备提供相匹配的凭证 1.1.3. 在存在共用终端设备的情况下&#xff0c;所有的这些问题将更加凸显 1.2…

打造未来交互新篇章:基于AI大模型的实时交互式流媒体数字人项目

在当今数字化浪潮中,人工智能(AI)正以前所未有的速度重塑我们的交互体验。本文将深入探讨一项前沿技术——基于AI大模型的实时交互式流媒体数字人项目,该项目不仅集成了多种先进数字人模型,还融合了声音克隆、音视频同步对话、自然打断机制及全身视频拼接等前沿功能,为用…

Python中使用正则表达式

摘要&#xff1a; 正则表达式&#xff0c;又称为规则表达式&#xff0c;它不是某种编程语言所特有的&#xff0c;而是计算机科学的一个概念&#xff0c;通常被用来检索和替换某些规则的文本。 一.正则表达式的语法 ①行定位符 行定位符就是用来描述字符串的边界。"^&qu…

第十三节、人物属性及伤害计算

一、碰撞器层级剔除 选中player和敌人&#xff0c;即可去除 若勾选触发器&#xff0c;则会取消掉碰撞效果&#xff0c;物体掉落 二、人数属性受伤计算 1、创建代码 将两个代码挂载到玩家和敌人身上 2、调用碰撞物体的方法 3、伤害值 开始&#xff1a;最大血量即为当前血量…