首先声明一下,我的临床数据三线表全是用excel生成的,但是全能的R语言也有能够自动生成的函数可用。
临床三线表往往是整个文章的第一个图标,所以又称为Table 1
。
正好两个R包都是这样的名字,其中一个是table1
。
这里有一个教程:
https://benjaminrich.github.io/table1/vignettes/table1-examples.html
可以通过别人的教程来学习,比如以下这一段就是教程里面的。
#install.packages("MatchIt")
rm(list = ls())
library(MatchIt)
data(lalonde)
lalonde$treat <- factor(lalonde$treat, levels=c(0, 1, 2), labels=c("Control", "Treatment", "P-value"))
lalonde$black <- factor(lalonde$black)
lalonde$hispan <- factor(lalonde$hispan)
lalonde$married <- factor(lalonde$married)
lalonde$nodegree <- factor(lalonde$nodegree)
lalonde$black <- as.logical(lalonde$black == 1)
lalonde$hispan <- as.logical(lalonde$hispan == 1)
lalonde$married <- as.logical(lalonde$married == 1)
lalonde$nodegree <- as.logical(lalonde$nodegree == 1)
#install.packages("table1")
library(table1)
## 添加标签
label(lalonde$black) <- "Black"
label(lalonde$hispan) <- "Hispanic"
label(lalonde$married) <- "Married"
label(lalonde$nodegree) <- "No high school diploma"
label(lalonde$age) <- "Age"
label(lalonde$re74) <- "1974 Income"
label(lalonde$re75) <- "1975 Income"
label(lalonde$re78) <- "1978 Income"
## 增加单位
units(lalonde$age) <- "years"
## 两个函数
rndr <- function(x, name, ...) {
if (length(x) == 0) {
y <- lalonde[[name]]
s <- rep("", length(render.default(x=y, name=name, ...)))
if (is.numeric(y)) {
p <- t.test(y ~ lalonde$treat)$p.value
} else {
p <- chisq.test(table(y, droplevels(lalonde$treat)))$p.value
}
s[2] <- sub("<", "<", format.pval(p, digits=3, eps=0.001))
s
} else {
render.default(x=x, name=name, ...)
}
}
rndr.strat <- function(label, n, ...) {
ifelse(n==0, label, render.strat.default(label, n, ...))
}
## 生成表格,竖线后面是分类
table1(~ age + black + hispan + married + nodegree + re74 + re75 + re78 | treat,
data=lalonde, droplevels=F, render=rndr, render.strat=rndr.strat, overall=F)
R语言的学习,主要就是学习函数,尤其是别人的函数,我们现在就是要把别人的函数高清楚,对接自己的数据。
通过运行教程,我知道了以下几点,
首先,这个R包的主要函数是table1
, 这个函数接受的是数据框。
这个数据框里面的每一列都可以选出来作为最终图的第一列(红框),还可以选出一列作为分层数据(蓝色框)
其次,每一个红框中的数据,如果是分类数据,需要转换为因子,label
这个函数可以改变分类的标题(蓝色箭头所指的黑色字),units
这个函数可以增加括号中的内容(红色箭头的years)
最后,最后一列pvalue本来是不支持的,但是通过增加因子的水平可以欺骗函数得到这一列。
接下来我们用自己的数据来试一试。
看看我们的数据,这个数据来自于TCGA的临床数据,最后一列融合了一个基因的表达数据,就是strat
那一列,最终用来分类数据。
改变每一个变量,首先是年龄,认为地用40分为两类,用factor
来因子化,用labels
改变名称,用units
函数增加括号内的内容。
library(table1)
data$age <- ifelse(rt_plot$age >= 40,"age >= 40","age <40")
data$age <- factor(data$age)
label(data$age) <- "Age"
units(data$age) <- "days"
按基因分为高表达和低表达两类,这里增加了levels的水平,目的是增加一列给pvalue。
data$strat <- ifelse(data$strat > median(data$strat),0,1)
data$strat <- factor(data$strat, levels=c(0, 1, 2), labels=c("LncRNA High", "LncRNA Low", "P-value"))
data$strat <- ifelse(data$strat > median(data$strat),0,1)
data$strat <- factor(data$strat, levels=c(0, 1, 2), labels=c("LncRNA High", "LncRNA Low", "P-value"))
以下依次修改的是性别,分期,样本类型和患者状态
data$gender <- factor(data$gender)
label(data$gender) <- "Gender"
data$stage<- factor(data$stage)
label(data$stage) <- "Stage"
data$sample<- factor(data$sample)
label(data$sample) <- "Sample"
data$fustat <- factor(data$fustat)
data$fustat <- as.logical(data$fustat == 1)
label(data$fustat) <- "Event"
现在模仿原文来构建两个辅助函数,用来算p值,实际上就是复制,把变量名称修改了一下。
rndr <- function(x, name, ...) {
if (length(x) == 0) {
y <- data[[name]]
s <- rep("", length(render.default(x=y, name=name, ...)))
if (is.numeric(y)) {
p <- t.test(y ~ data$strat)$p.value
} else {
p <- chisq.test(table(y, droplevels(data$strat)))$p.value
}
s[2] <- sub("<", "<", format.pval(p, digits=3, eps=0.001))
s
} else {
render.default(x=x, name=name, ...)
}
}
rndr.strat <- function(label, n, ...) {
ifelse(n==0, label, render.strat.default(label, n, ...))
}
现在,如果没有意外,我们就可以出图了
用的是主函数table1
,竖线前面是变量,竖线后面是分类变量
table1(~ gender + age + stage+fustat+sample| strat,
data=data, droplevels=F, render=rndr, render.strat=rndr.strat, overall=F)
好了,顺利得到效果,原教程里面还有很多样图可以模仿,我这里只是给出一种方法,剩下的大家自己去探索。
如果像获得excel,可以用另外一个R包,tableone
,教程在这里。
https://cran.r-project.org/web/packages/tableone/vignettes/introduction.html
我是果子,明天见。
网友评论