临床信息不会整理?10分钟让你搞定发表级表格制作,看完我就服了!(附详细代码)
快速完成TCGA数据集临床基线表的整理
大家好,我是阿琛。在生信分析的文章中,往往第一张表格是基于TCGA数据库患者临床信息的基线资料表,以展示分析的整体水平。在前面的内容中,我们学习了使用tableone包中相关的函数来快速的制作临床基线资料表(“R语言一键生成好看的Table 1?小白也能十分钟之内搞定!”)。
接下来,我们来看下如何基于下载得到TCGA临床数据,逐步完成整个表格的整理内容,同时来看一下数据清洗和字符串匹配相关内容的应用。
下面,我们来看下如何基于TCGA数据的临床信息绘制临床基线资料表。
首先,使用TCGAbiolinks包下载TCGA-LIHC患者的相关临床信息。
library(TCGAbiolinks)
clinical <- GDCquery(project = "TCGA-LIHC",
data.category = "Clinical",
file.type = "xml")
GDCdownload(clinical)
cliquery <- GDCprepare_clinic(clinical, clinical.info = "patient")
save(cliquery, file = "TCGA-LIHC.clinical.rda")
将下载结果保存为rda文件。可以看到,在当前目录下多了一个.rda文件,后续在使用时直接使用load()函数进行读取即可。在结果中,其中包含415个患者的82个不同的临床信息。
#load("TCGA-LIHC.clinical.rda")
colnames(cliquery)[1] <- "Tumor_Sample_Barcode"
cliquery[1:3,1:3]
write.csv(cliquery, "TCGA-LIHC.Clinical.csv")
将临床信息的第一列列名修改为“TumorSampleBarcode”,便于后续分析处理;同时将其保存为csv文件。
rm(list = ls())
library(tidyverse)
rt <- read.csv("TCGA-LIHC.Clinical.csv")
接下来,读取保存好的临床信息,用于后续的临床数据整理和分组筛选。在这里,为了演示方便,我们通过存活和死亡的方法来对所有患者进行分组作为演示。
p1 = rt %>%
filter(vital_status == "Alive")
p2 = rt %>%
filter(vital_status == "Dead")
cli = rt %>%
filter(vital_status != "")
简单解释一下:分别根据临床信息数据框中“vital_status”的信息,筛选“Alive”的患者作为存活组别,筛选“Dead”的患者作为死亡组别,同时去除其中缺失的患者后,作为纳入的所有患者。当然,在实际应用过程中,也可以根据自己的数据需求,对患者进行重新分组。
可以看到,最终纳入分析对患者中,存活的患者为315例,死亡的患者为100例,总计415例。
接着,对临床数据进行整理,首先对当前分组下性别数据内容进行整理。
s1 = p1 %>%
group_by(gender) %>%
summarise(alive=n())
s1
这里,使用group_by()函数结合summarise()函数,分别统计存活Alive的患者中男性和女性数量。结果显示,其中女性96个,男性219个。
s2 = p2 %>%
group_by(gender) %>%
summarise(dead=n())
s2
同样,对死亡患者进行整理。结果显示,在死亡dead的患者中女性40个,男性60个:
接着,使用merge()函数对两个统计分析结果进行合并。
sex <- merge(s1, s2, by='gender', all = TRUE) %>%
as.data.frame
sex
rownames(sex) <- sex[,1]
sex <- sex[,-1]
结果显示:
随后,使用chisq.test()函数进行卡方检验,对统计结果进行分析,计算对应的P值。
sex.p = chisq.test(sex)$p.value
print(sex.p)
结果显示,经过卡方检验,P值为0.099,说明性别在死亡和存活患者之间无显著性差异。
sex$total <- rowSums(sex)
sum <- colSums(sex)
##计算百分比并写到括号里
#用sprintf格式化为小数点后保留1位,加上百分号
sex <- rbind(c(NA, NA, NA),
paste0(sex[1,], " (", sprintf("%1.1f%%", sex[1,]/sum*100), ")"),
paste0(sex[2,], " (", sprintf("%1.1f%%", sex[2,]/sum*100), ")"))
#加上行名、列名
rownames(sex) <- c("Sex", "Female", "Male")
colnames(sex) = paste0(c("Alive", "Dead", "Total"),
"\n(n=", sum, ")")
print(sex)
最后,对细节信息进行整理,统计添加所有患者数量,分别对行名和列名进行设置,同时添加百分比。
结果显示:
随后,选取一个数值型变量,来看看如何对数值型变量进行整理分析。在此,我们来对患者的年龄情况进行统计分析。
age1 <- p1 %>%
summarise(age = round(mean(age_at_initial_pathologic_diagnosis,na.rm = T), 1),
sd = round(sd(age_at_initial_pathologic_diagnosis,na.rm = T), 1),
median=round(median(age_at_initial_pathologic_diagnosis,na.rm = T), 1),
min=round(min(age_at_initial_pathologic_diagnosis,na.rm = T), 1),
max=round(max(age_at_initial_pathologic_diagnosis,na.rm = T), 1)
)
age1 <- c("Age(Mean (SD))" = with(age1, paste0(age, " (", sd, ")")),
"Age(Median [MIN, MAX])" = with(age1, paste0(median, " [", min, ",", max, "]"))
)
计算分组1存活的患者中相应年龄的平均数(SD值),中位数(最小值,最大值)。使用summarise()函数来进行统计,包括mean,sd值,中位值,min和max,同时使用round()函数来设置保留小数点后一位。将计算得到的结果使用paste0()函数进行整合成标准形式。
age2 <- p2 %>%
summarise(age = round(mean(age_at_initial_pathologic_diagnosis,na.rm = T), 1),
sd=round(sd(age_at_initial_pathologic_diagnosis,na.rm = T), 1),
median=round(median(age_at_initial_pathologic_diagnosis,na.rm = T), 1),
min=round(min(age_at_initial_pathologic_diagnosis,na.rm = T), 1),
max=round(max(age_at_initial_pathologic_diagnosis,na.rm = T), 1)
)
age2 <- c("Age(Mean (SD))" = with(age2, paste0(age, " (", sd, ")")),
"Age(Median [MIN, MAX])" = with(age2, paste0(median, " [", min, ",", max, "]"))
)
同样的,对死亡的患者年龄进行统计分析。
age <- cli %>%
summarise(age = round(mean(age_at_initial_pathologic_diagnosis,na.rm = T), 1),
sd=round(sd(age_at_initial_pathologic_diagnosis,na.rm = T), 1),
median=round(median(age_at_initial_pathologic_diagnosis,na.rm = T), 1),
min=round(min(age_at_initial_pathologic_diagnosis,na.rm = T), 1),
max=round(max(age_at_initial_pathologic_diagnosis,na.rm = T), 1)
)
age <- c("Age(Mean (SD))" = with(age, paste0(age, " (", sd, ")")),
"Age(Median [MIN, MAX])" = with(age, paste0(median, " [", min, ",", max, "]"))
)
最后,对所有患者的年龄进行统计分析。这样,在环境变量中多了三个年龄的计算结果。
结果显示:
age <- cbind(age1, age2) %>%
cbind(age)
colnames(age) <- colnames(sex)
print(age)
使用cbind()函数将三个的统计结果进行合并,并将性别sex中整理好的列名赋值给年龄age。
结果显示:
在此,呈现了两种连续变量的展示形式;在实际使用过程中,任选其中一种方法进行展示即可。
在肿瘤分析过程中,肿瘤分期是个重要信息。接下来,对肿瘤分期进行分组整理。
stage_a <- p1 %>%
filter(stage_event_pathologic_stage != "") %>%
group_by(stage_event_pathologic_stage) %>%
summarise(stage = n())
stage_d <- p2 %>%
filter(stage_event_pathologic_stage != "") %>%
group_by(stage_event_pathologic_stage) %>%
summarise(stage = n())
stage_t <- cli %>%
filter(stage_event_pathologic_stage != "") %>%
group_by(stage_event_pathologic_stage) %>%
summarise(stage = n())
筛选-分组-统计。去除分期Stage中缺失的患者,并按pathologic_stage分组情况进行分组,然后使用summarise()函数进行统计汇总。
接着,对三组临床分期进行合并。这里使用merge()函数进行数据的合并;注意一点的是,记得加上参数all = TRUE,表示即使另一组为缺失值,这个变量分组依然会保存。
stage <- merge(stage_a, stage_d, by="stage_event_pathologic_stage", all = TRUE) %>%
merge(stage_t, by="stage_event_pathologic_stage", all = TRUE) %>%
as.data.frame
结果显示:
随后,对行名和列名进行设置。
rownames(stage) <-stage[,1]
stage <-stage[,-1]
colnames(stage) <-colnames(sex)
print(stage)
结果显示:
随后,计算两组之间的统计显著性差异。既然是计算存活和死亡之间组别的差异,那么自然需要将第三组total去掉,并将其赋值给一个新变量。
sgx <- stage[, -3]
sgx <- sgx[!apply(sgx, 1, anyNA),]
sg.p = chisq.test(sgx)$p.value
去除包含NA的分组,随后使用chisq.test()函数进行卡方检验。
结果显示:
最后,将最后的结果汇总输出。首先,将缺失值以NA代替,同时与性别一样,计算其各个值所占的百分比,并保留一位小数。随后,对行名和列名进行相应的设置。
sgv2 <- lapply(1:nrow(stage), function(i) ifelse(is.na(stage[i,]), NA,
paste0(stage[i,],
" (", sprintf("%1.1f%%", stage[i,]/sum * 100), ")")))
sgv2 <- do.call(rbind, sgv2)
rownames(sgv2) <- rownames(stage)
colnames(sgv2) <- colnames(stage)
sgv <- rbind(c(NA, NA, NA),
sgv2)
rownames(sgv)[1] <- "Stage"
print(sgv)
结果显示:
res = rbind(sex, age) %>%
rbind(sgv) %>%
as.data.frame
print(res)
最后,使用rbind()函数将性别,年龄,和分期信息进行合并,并使用as.data.frame()函数将结果转换为数据框格式。
结果显示:
所有内容都整理好了,最后将结果以csv形式输出,并命名为TABLE1.csv。
tab <- print(res,
quote = FALSE, #不显示引号
noSpaces = TRUE,
printToggle = FALSE)
write.csv(tab, file = "TABLE1.csv")
注意,使用参数quote = FALSE将引号去除,其余默认。可以看到,在当前工作目录下多了一个名为TABLE1.csv的结果文件。
结果显示:
这样,一份基于生存情况都基线资料表就整理好了~当然,如果你对其他信息感兴趣的话,也可以进行相应的整理。
回复“阿琛54”即可获得相应的代码和数据~
系列传送门
R语言小白入门课|一刻钟带你学会R数据转化
—
END—
撰文丨阿 琛
排版丨四金兄
值班 | 火 火
主编丨小雪球
阅读原文 最新评论
推荐文章
作者最新文章
你可能感兴趣的文章
Copyright Disclaimer: The copyright of contents (including texts, images, videos and audios) posted above belong to the User who shared or the third-party website which the User shared from. If you found your copyright have been infringed, please send a DMCA takedown notice to [email protected]. For more detail of the source, please click on the button "Read Original Post" below. For other communications, please send to [email protected].
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。