《R语言医学数据分析实战》学习记录|第三章 数据框的操作

news/2025/11/28 20:16:39/文章来源:https://www.cnblogs.com/minibenifit/p/19258067

第三章 数据框的操作

内容记录

TLDR记录

  1. 数据框结构数据的基本属性(清单列表:head(),tail(),摘要数据:str(),epiDisplay::des())
  2. 操作数据框数据:选取子集subset(),增删元素
  3. dplyr包对数据框数据的操作:筛选,排序,增删变量,统计分析,拆分合并
  4. 数据框的长宽转换,一般应转换为长格式。
  5. 缺失值的识别和处理(删除、常规替换、插值补全)。

RAW记录

  1. 数据框的基本属性(和pandas中的dataframe非常像):head(),tail(),names(),str(),attributes(),attr(),attributes()$var.labels,epiDisplay::des()
library(epiDisplay)
# 加载数据
data(Familydata)
# 探索数据结构structure
str(Familydata)
# 分别显示数据属性的全部信息
attributes(Familydata)
# 为var.labels变量的第一个和最后一个赋值
attr(Familydata, "var.labels")[1] <- "Identification Number"
attr(Familydata, "var.labels")[6] <- "Gender"
# 查看var.labels变量
attributes(Familydata)$var.labels
# des函数属于epiDisplay包,三方工具查看数据属性
des(Familydata)
  1. 数据框的操作:子集选取subset(),随机取样sample(),排序order(),查重duplicated(),增删元素,感叹号!使得值取反,减号-取相反数;尽量避免将数据框添加到搜索路径中(个人意见)。
  • 取子集的不同方式
# 以下两表达式等价
Familydata[,3]
Familydata$ht
# 以下两表达式等价
Familydata[1:3,c(3,4,6)]
Familydata[1:3,c("ht","wt", "sex")]
# 以下两表达式等价
Familydata[Familydata$sex == "F",]
subset(Familydata, sex == "F")
# subset函数变量2筛选行,变量3筛选列
subset(Familydata, sex == "F", select = c("ht", "wt"))
sample.rows <- sample(1:nrow(Familydata), size = 3)
sample.rows
# 得到的行顺序和sample.rows顺序一致
Familydata[sample.rows, ]
# 以下两表达式等价
# Familydata$age默认为升序,取-后变降序
Familydata[order(Familydata$age, decreasing = TRUE),]
Familydata[order(-Familydata$age), ]
# 以下示例如何删除重复的行
Familydata1 <- Familydata
Familydata1[12, ] <- Familydata[2, ]
table(duplicated(Familydata1$code))
which(duplicated(Familydata1$code))
# !操作使FALSE为TRUE
unique.code.data <- Familydata1[!duplicated(Familydata1$code),]
identical(unique.code.data, Familydata)
  • 参考资料:在R中如何正确地使用减号/集补运算符?-腾讯云开发者社区-腾讯云
  1. dplyr包:统一的更规范高效地处理数据
  • 按行筛选:filter()slice(),stats里有同名filter函数;按某变量做行排序arrange();按列筛选select(),MASS包有同名select;
library(dplyr)
data(birthwt, package = "MASS")
filter(birthwt, age > 35)
filter(birthwt, age > 35, bwt<2500 | bwt >4000)
# slice是按行号筛选
slice(birthwt, 3:6)
# arrange默认是升序
arrange(birthwt, bwt, age)
# 以下两表达式等价
arrange(birthwt, desc(bwt))
arrange(birthwt, -bwt)
select(birthwt, bwt, age, race, smoke)
  • 不改变原dataframe增加元素/属性:添加新变量(新列)mutate(data, 变量名=表达式value),变量名已存在则替代原变量;增加统计量summarise(data, (变量名=)统计量计算表达式);分组group_by(, 列名)不改变dataframe结构增加分组属性;

  • 传递符%>%,组合连接多个操作(函数),前一个操作的输出结果代替后一个操作的第一个输入参数。

以下代码的目的:将birthwt数据中的race变量转换成因子变量并添加对应标签,按race分组,计算各组中bwt的平均值

birthwt %>%mutate(race = factor(race, labels = c("white", "black", "other"))) %>%group_by(race) %>%summarise(mean(bwt))
  1. 数据框的合并:纵向合并rbind(),row-bind;横向合并cbind(),column-bind;按共有变量合并merge(data1, data2, by = "id"),或dplyr::full_join(data1, data2, by = "id");dplyr有相同功能的系列函数:bind_rows(),bind_cols(),left_join(),right_join();

  2. 数据框形式的长宽变换

  • 系统自带函数reshape(),但参数名不清晰,具体使用时看help了解参数;
  • 简洁版函数:tidyr::pivot_wider(data,names_from="从原数据中获得新数据的列名来源",values_from="从数据中获得新数据的值来源" )tidyr::pivot_longer(data, cols(从原数据获得新的宽数据的关键列),names_to="原数据中的列名变成新数据的某一列的值,这个列的名字",values_to="原数据中的值变成新数据的某一列的值,这个列名")
  • 数据分析之前一般应转换为长格式。
  1. 缺失值的处理
  • 识别缺失值is.na(),系统内置函数对NA值的处理
# 以mean函数为例了解函数自带对NA值的处理
height <- c(100,150,NA,160)
# 以下两表达式结果等价
mean(height, na.rm = TRUE)
mean(na.omit(height))
# 区别:na.omit()是独立函数,忽略输入对象中的缺省值,na.rm只是函数的一个内部参数
# 部分函数“天生”忽略NA值,如summary
summary(height)
  • 探索缺失值:以经典的iris数据集来举例NA值的探索模式
library(missForest)
data("iris")
# 生成随机数种子,使结果具有可重复性
set.seed(1234)
# prodNA函数来自missForest包,人为产生NA值,默认生成10%的数据为NA(noNA参数控制)
iris.miss <- prodNA(iris)
summary(iris.miss)
library(VIM)
# VIM::aggr()函数展示NA值的分布情况,具体函数和参数介绍见第4章
aggr(iris.miss, prop=FALSE, numbers=TRUE, cex.axis=0.7)
  • 填充缺失值的常用方式:(1)删除,删除带有缺失值的变量或记录,如na.omit();(2)替换,用均值、中位数、众数或其他值替代,如均值mean()填充;(3)补全,基于统计模型推测和补充缺失值,如多重插补函数包library(mice)
# 1. 缺失值数量很小时,可以做删除操作。
# 以下两行语句等价
iris.sub <- na.omit(iris.miss)
iris.sub <- iris.miss[complete.cases(iris.miss),]
# 2. 不想删除缺失值时,可以用特定值替代,比如平均值
Sepal.Length.Mean <- mean(iris.miss$Sepal.Length, na.rm = TRUE)
iris.miss1 <- iris.miss
iris.miss1$Sepal.Length[is.na(iris.miss1$Sepal.Length)] <- Sepal.Length.Mean
# 查看补齐后的数据分布情况,可以看到偏差平均在0.6%,极值在25%左右
summary((iris$Sepal.Length-iris.miss1$Sepal.Length)/iris$Sepal.Length)
# 3. 多重插补(multiple imputation)是基于重复模拟的处理缺失值的方法。R中实现该方法的包有Amelia、mi、mice等。其中 mice 包使用链式方程的多变量补全法。mice包假设数据是随机缺失的,并根据变量的类型建立模型得到预测值以代替缺失值。
# 常用预测方法有:(1)预测均值匹配(pmm),实质上就是线性回归,适用于数值型变量;(2)Logistic 回归 (logreg),适用于二分类变量;(3)多分类 Logistic回归(ployreg),适用于无序多分类变量;(4)比例优势比模型(polr),适用于有序多分类变量。
# 用函数 mice()补全数据框 iris.miss 里的缺失值。
library(mice)
imputated.data <- mice(iris.miss, seed = 1234)
summary(imputated.data)
# 输出结果的矩阵 PredictorMatrix 里,每一行代表含有缺失值的变量名,如果该行对应的某一列元素为 1,代表该列变量被用于建模预测。本例中,对于每一个变量,其余变量都被用于它的缺失值预测。
# 函数 mice( ) 的输出结果是一个列表,其中的对象 imp 也是一个列表,存放的是每个变量缺失值的插补值。
# 观察生成的Sepal.Length的值可知,mice函数通过Gibbs抽样完成5次随机抽样(5列)。
imputated.data$imp$Sepal.Length
# 选择其中第3组来补全
complete.data <- complete(imputated.data, 3)
# 对于数值型变量,可以计算插补值与原始变量值的偏差。
summary((iris$Sepal.Length-complete.data$Sepal.Length)/iris$Sepal.Length)
# 查看补齐后的数据分布情况,可以看到偏差平均在0.07%,极值在9%-14%左右。比均值方法好。
table(iris$Species, complete.data$Species)
# 这种表被称为混淆矩阵(confusion matrix),经常用于评价模型预测的准确度。对角线上的数字代表预测值和真实值一致的个数,非对角线上的数字代表预测值和真实值不一致的个数。从上面的输出结果可以看出,变量 Species 的19个缺失值插补的正确率约为100%。
  1. 大型数据的处理策略
  • 清理工作空间:rm(list = ls(all = TRUE));ls()显示当前工作空间的对象,参数all=TRUE则清除对象包括隐藏对象。
rm(list = ls(all = TRUE))
  • 读取csv文件:utils系统自带的read.csv(),对于大型数据,处理速度很慢;readr::read_csv()data.table::fread()。三个函数读取速度递增,最后一个学习成本高,但值得投入时间学习。

  • 模拟大数据集:rnorm()生成服从标准正态分布的随机数

# 模拟生成一个50000*200的数据集
bigdata <- as.data.frame(matrix(rnorm(50000*200),ncol = 200))
# 快速生成一个200个变量的变量名群
varnames <- NULL
for(i in letters[1:20]){for (j in 1:10){varnames <- c(varnames, paste(i, j, sep = "_"))}
}
names(bigdata) <- varnames# 如果不想用循环产生名字,可以用以下方式
# apply函数会产生多余空格
# apply(expand.grid(1:20, letters[1:20]), 1, function(x) paste(x[2], x[1], sep="_"))
sprintf("%s_%s", expand.grid(1:10,letters[1:20])[,2],expand.grid(1:10,letters[1:20])[,1])
as.vector(t(outer(letters[1:20], 1:10, paste, sep="_")))
  • 剔除不需要的变量:tidyselect包的starts_with()ends_with()contains()函数辅助做筛选过程。
library(tidyselect)
library(dplyr)
# 按前缀或后缀选择
subdata1 <- select(bigdata, starts_with("a"))
names(subdata1)
subdata2 <- select(bigdata, ends_with("2"))
names(subdata2)
# 按或关系筛选数据,a开头或b开头
subdata3 <- select_at(bigdata, vars(starts_with("a"), starts_with("b")))
names(subdata3)
# 按包含关系筛选
subdata4 <- select_at(bigdata, vars(contains("1")))
names(subdata4)
# contains("1")是包含10的数字的,下方式可去除
subdata4.1 <- select_at(bigdata, vars(contains("1"), -contains("10")))
names(subdata4.1)
# 要剔除指定变量,在对应函数前加上-号
subdata5 <- select_at(bigdata, vars(-contains("1"), -contains("5")))
names(subdata5)
  • 选取随机样本:随机采样函数sample_n(data, size = 行数)sample_frac(data, size = 抽样比例)
sampledata1 <- sample_n(bigdata, size = 500)
nrow(sampledata1)
sampledata2 <- sample_frac(bigdata, size = 0.02)
nrow(sampledata2)

习题

3-1 构建一个数据集:

下表中的数据来源于某地方病研究机构关于大骨节病患儿的一项调查研究。其中肌酐含量为 24 小时测得的尿肌酐(单位为 mmol)。分类变量 group 中,0 代表未患病(正常)儿童,1 代表患病儿童。(1)将数据录入 R 并保存为数据框 UCR;(2)为数据框和数据框中的变量加上合适的标签;(3)将添加标签后的数据框保存为 R 数据文件 UCR.rdata。

# 构建数据
age <- c(13, 11, 9, 6, 8, 10, 12, 7, 10, 9, 11, 12, 15, 16, 8, 7, 10, 15)
ucr <- c(3.54, 3.01, 3.09, 2.48, 2.56, 3.36, 3.18, 2.65, 3.01, 2.83, 2.92, 3.09, 3.98, 3.89, 2.21, 2.39, 2.74, 3.36)
group <- c(rep(0,8), rep(1,10))
group <- factor(group, levels = 0:1, labels = c("Normal", "Patient"))
UCR <- data.frame(age, ucr, group)# 设置属性
str(UCR)
attr(UCR, "datalabel") <- "UCR in Kaschin-Beck disease children"
attr(UCR, "var.labels") <- c("Age in years", "Urine creatinine (mmol)", "Type of children")# 保存数据
save(UCR, file = "UCR.rdata")

3-2 导入上述数据,并选取患者的子数据集

将上面创建的数据文件 UCR.rdata 导入 R 中,并选取患病儿童的子数据集。

load("UCR.rdata")
subset(UCR, group == "Patient")

3-3 导入Planning数据集,查看数据信息并整理数据

epiDisplay 包里的数据集 Planning 来自 20 世纪 80 年代中期泰国的一项计划生育调查研究,请通过其帮助文件查看数据信息并整理该数据集。

library(epiDisplay)
data(Planning)
# 观察数据概况:列描述des() 数据统计摘要summary()
des(Planning)
names(Planning) <- tolower(names(Planning))   # 把变量名变为小写字母
summary(Planning)table(duplicated(Planning$id))       # 查看是否有重复id
which(duplicated(Planning$id))       # 找出重复id的行号
Planning$id
Planning$id[216] <- 216              # 修正重复idlibrary(dplyr)
Planning <- mutate(Planning,relig = ifelse(relig == 9, NA, relig),     # 将变量relig中的9变成NAped = ifelse(ped == 0 | ped == 9, NA, ped), # 将变量ped中的0和9变成NAincome = ifelse(income == 9, NA, income),   # 将变量income中的9变成NAam = ifelse(am == 99, NA, am),           # 将变量am中的99变成NAreason = ifelse(reason == 9, NA, reason),  # 将变量reason中的9变成NAbps = ifelse(bps == 0 | bps == 999, NA, bps), # 将变量bps中的0和999变成NAbpd = ifelse(bpd == 0 | bpd == 999, NA, bpd), # 将变量bpd中的0和999变成NAwt = ifelse(wt == 0 | wt > 99, NA, wt),    # 将变量wt中的0和大于99的值变成NAht = ifelse(ht == 0 | ht > 300, NA, ht)    # 将变量ht中的0和大于300的值变成NA
)
# 数据结构str()
str(Planning)

3-4 长格式和宽格式的互相转换

MASS 包里的数据集 bacteria 是长格式,其中的变量 week 为时间变量,变量 y 为结局变量。试将其转换成宽格式,然后再将宽格式数据重新转换回原来的长格式。请注意数据中的缺失值。

使用函数reshape()

data(bacteria, package = "MASS")
wide <- reshape(bacteria, idvar = "ID", timevar = "week", v.names = "y", direction = "wide") 
long <- reshape(wide, idvar = "ID", varying = list(5:9), v.names = "y", direction = "long") 
long <- na.omit(long)

使用tidyr包

library(tidyr)
wide <- pivot_wider(bacteria, names_from = week, values_from = y)
long <- pivot_longer(wide, -c(1:4),names_to = "week", values_to = "y")
long <- na.omit(long)

3-5 使用mice包计算补齐

试探索 VIM 包的数据集 sleep 中的缺失值模式,并使用 mice 包补全缺失数据。

library(VIM)
data(sleep)
aggr(sleep, prop = FALSE, numbers = TRUE)
summary(sleep)library(mice)
# 设立随机数种子,使用mice函数补全NA值形成补全值的dataframe
imp <- mice(sleep, seed = 1234)
complete.data <- complete(imp, 3)
summary(complete.data)

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

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

相关文章

软件工程学习日志2025.11.28

📋 实验内容概述 本次实验分为两大部分:Linux基础命令操作和Hadoop环境实践,旨在为后续大数据实验打下坚实的基础。 🎯 具体完成内容 一、Linux操作部分(2.5小时)目录操作命令成功掌握的cd命令操作 cd /usr/lo…

2025年11月晶振厂家推荐:权威榜与选择指南

在电子元器件领域,晶振作为时钟频率的核心部件,其性能直接影响整个系统的稳定性和可靠性。随着5G通信、物联网、汽车电子等行业的快速发展,市场对高精度、高稳定性晶振的需求持续增长。许多工程师、采购人员或企业决…

2025年11月晶振厂家推荐榜单:主流厂商综合对比与选择指南

在电子设备日益精密的今天,晶振作为时钟频率的核心元件,其稳定性与可靠性直接关系到整个系统的性能。无论是通信基站、工业控制、汽车电子还是消费类产品,工程师在选择晶振厂家时往往面临诸多考量,例如厂家的技术实…

漏洞赏金猎人的深度侦察方法论 | 第一部分

本文详细介绍了漏洞赏金猎人的侦察方法论,包括范围审查、子域名枚举等关键步骤,帮助安全研究人员系统性地发现潜在漏洞和安全风险。漏洞赏金猎人的深度侦察方法论 | 第一部分 仅供会员阅读的故事 作者:Abhijeet Kum…

2025年11月晶振厂家推荐:权威榜单与选择指南

在电子元器件领域,晶振作为时钟频率的核心部件,其性能直接影响整机设备的稳定性和可靠性。随着5G通信、物联网、汽车电子等产业的快速发展,市场对高精度、高稳定性晶振的需求持续增长。根据行业报告显示,全球晶振市…

高效且常用的国产AI工具

一是“工具线”:本书详解了16个高效且常用的国产AI工具,包括文心一言、Kimi、WPSAI、百度文库、橙篇、豆包、通义、智谱清言、秘塔、文心一格、天工AI、讯飞星火、360智绘、剪映、即梦AI及可灵AI,并且随书再附赠10款…

2025年11月晶振厂家推荐榜单:主流厂商综合对比选择指南

在电子元器件采购与供应链管理过程中,晶振作为时钟频率核心元件,其稳定性与可靠性直接影响整机性能。随着5G通信、物联网、汽车电子等新兴领域快速发展,市场对高精度、低功耗、小型化晶振需求持续增长。根据工信部2…

2025年11月晶振厂家推荐榜单:知名品牌综合对比与选购指南

在电子元器件领域,晶振作为时钟频率的核心元件,其性能稳定性直接影响到整个电路系统的可靠性。随着5G通信、物联网、汽车电子等行业的快速发展,市场对高精度、低功耗、小尺寸晶振的需求持续增长。根据行业权威报告显…

YXC扬兴科技联系方式:产品服务与技术支持相关指南

深圳扬兴科技有限公司(下面简称:YXC),自2010年成立以来,一直专注于时钟频率器件的研发、生产和销售,是业界领先的半导体高新技术企业。 公司主营产品包括晶振、可编程振荡器、VCXO/TCXO/OCXO、三级钟、锁相环芯片…

13.2.3.Tomcat - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

选择性检索增强代码补全技术解析

介绍一种基于自监督学习的代码补全方法,通过选择性检索机制在保持准确性的同时将推理速度提升70%,解决了大型代码仓库中跨文件依赖的智能补全问题。选择性检索增强的仓库级代码补全 大型代码模型在基于上下文完成任意…

W55MH32 网络继电器三模自由控制:小程序按键网页随选 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Day49(19)-F:\硕士阶段\Java\课程代码\后端\web-ai-code\web-ai-project02\tlias-web-management

登录设置HTTP:无状态响应:本次响应不携带上一次响应内容cookieJWT令牌老版本 package com.itheima;import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; impor…

Azure DevOps Server 2022.2 补丁(Patch 7)

Azure DevOps Server 2022.2 补丁(Patch 7)Azure DevOps Server RC版本在持续改进中,但是不影响上一个大版本的修复补丁进度;今天,微软又按照管理发布了月度补丁:Azure DevOps Server 2022.2 补丁(Patch 7),补…

U636462 无根树

noip 前一天锻炼手感。 设 \(f_i\) 为 \(i\) 到终点的答案。 那么每次转移 \(u\) 这个点的时候,令其出点 \(v\) 的贡献为 \(w + f_v\),那么敌人一定会选择最小的 \(d\) 个点办掉,此时你的答案一定为第 \(d + 1\) 小…

人工智能:用Gemini3一分钟生成手势控制3D粒子交互系统

@目录前言一、Gemini3 Build界面准备二、精准提示词设计(核心步骤)提示词设计逻辑解析:三、效果演示(生成后功能实测)1. 手势控制粒子缩放与扩散2. 多模型切换功能3. 颜色自定义功能4. 简洁现代的界面与全屏控制预…

酶蛋白定向进化难题?泰克生物酵母展示服务,高效筛选“高活性酶”突变体

在工业催化、生物制药、酶制剂研发领域,天然酶往往存在活性不足、稳定性差、特异性低等局限,难以满足实际应用需求。而酶的定向进化是解决这一问题的核心技术 —— 通过构建突变文库、筛选高活性突变体,让酶的性能实…

2025年免费简历模板排行榜:媲美付费版的优质选择

全球经济格局持续演变,求职市场呈现出新的挑战与机遇。在这样的背景下,简历不再仅仅是个人信息的罗列,更是求职者专业能力、个人品牌以及与岗位匹配度的综合体现。然而,对于预算有限的求职者而言,如何免费获得媲美…

考场备忘录

策略相关 核心思想是先保证一等,然后冲 300,有可能就冲击队线。 先看题,确保理解题意的情况下可以进行若干时间思考,但是要 15min 内看完所有题目。A、B 有多快写多快,最坏要控制在 10 点前写完。如果真的 1.5h 还…

软件测试:基本概念二

无文档情况下的测试 这是一个非常现实且常见的问题。在很多中小企业或敏捷团队中,正式的需求文档(PRD)确实可能缺失或不完善。但这并不意味着测试无法进行,反而对测试人员提出了更高的要求——从“需求验证者”转变…