- 写在前面
- y为变量,x为分组的自动表格
- x为连续看变量, y为不同分组
写在前面
我们在分析数据的时候,第一步是对数据进行简单的描述。其实也就是所谓的tableone
。R语言有很多自动生成表格的包比如tableone
或者table1
。这样是很容易让我们对数据进行基本的统计的。
但是像tableone
这种的,我们只能要求数据分析的行是变量,列是分组。当我们有一个连续性变量在不同的分组之间的差异的时候,就十分的麻烦。这个时候可以自己设置一个函数来进行统一的分析。PS:这个没有找到相对应的包,如果有的知道的话,可以告诉一下。
y为变量,x为分组的自动表格
这样分析的目的,经常是我们要观察在不同的case和contorl组之间,分析的变量有没有差异。
我们可以使用tableone
当中的CreateTableOne
创建表达。
这个函数当中,常用的参数包括:
-
vars
:定义需要分析的变量, -
factorVars
定义需要分析的变量当中哪些是因子型变量。 -
strata
来定义分组。 -
data
来定义分析的数据集。
### 加载所需要的包
library(tableone)
library(survival)
### 加载示例数据集合
data(pbc)
### 定义统计的变量
myVars <- c("time", "status", "age", "sex")
## 定义因子变量
catVars <- c("status", "sex")
tab1 <- CreateTableOne(vars = myVars, strata = "trt" , data = pbc, factorVars = catVars)
tab1
## Stratified by trt
## 1 2 p test
## n 158 154
## time (mean (SD)) 2015.62 (1094.12) 1996.86 (1155.93) 0.883
## status (%) 0.894
## 0 83 (52.5) 85 (55.2)
## 1 10 ( 6.3) 9 ( 5.8)
## 2 65 (41.1) 60 (39.0)
## age (mean (SD)) 51.42 (11.01) 48.58 (9.96) 0.018
## sex = f (%) 137 (86.7) 139 (90.3) 0.421
通过上面的定义我们可以得到所有的分组统计结果,对于分类变量。默认的是显示n-1
个水平。我们可以通过showAllLevels
参数调整出来
tab2 <- print(tab1, showAllLevels = T)
## Stratified by trt
## level 1 2 p test
## n 158 154
## time (mean (SD)) 2015.62 (1094.12) 1996.86 (1155.93) 0.883
## status (%) 0 83 (52.5) 85 (55.2) 0.894
## 1 10 ( 6.3) 9 ( 5.8)
## 2 65 (41.1) 60 (39.0)
## age (mean (SD)) 51.42 (11.01) 48.58 (9.96) 0.018
## sex (%) m 21 (13.3) 15 ( 9.7) 0.421
## f 137 (86.7) 139 (90.3)
对于生成的表格,如果想要保存下来,之前是使用officer
来进行导出的。最近发现,只需要更改一下数据类型也就可以导出了。
tab3 <- as.matrix(tab2)
write.csv(tab3, "tab.csv", quote = F)
x为连续看变量, y为不同分组
这样的表达,经常是看,某一个连续性在不同分组之间的差异情况。例如:我们想要看某一个基因在不同临床参数下是否有差异。这个时候如果用tableone
的话,我们需要定义多次分组。然后得到的结果还要转至过来十分的麻烦。因此可以写一个简单的函数得到我们想要的结果。
library(tidyverse) ##函数很多函数是这个包的,所以要提前加载
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.2.1 ──
## ✔ ggplot2 3.2.1 ✔ purrr 0.3.2
## ✔ tibble 2.1.3 ✔ dplyr 0.8.3
## ✔ tidyr 0.8.3 ✔ stringr 1.4.0
## ✔ readr 1.3.1 ✔ forcats 0.4.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
TableOneStat <- function(dat, group, var, Normal = TRUE){
datexpr <- dat[c(var, group)]
datexpr <- na.omit(datexpr)
datexpr$num <- as.numeric(as.factor(datexpr[[group]]))
len <- length(unique(datexpr[[group]]))
if(Normal == T){
result <- datexpr %>% group_by(!!sym(group)) %>%
summarise(n = n(), mean = mean(!!sym(var), na.rm = T),
sd = sd(!!sym(var), na.rm = T)) %>%
mutate(summarise = paste0(round(mean,3), "±", round(sd,3)),
category = group) %>%
select(category,level = group, n, summarise)
if(len == 2){
p.val <- t.test(datexpr[[var]], datexpr[["num"]])$p.val
result$p.val <- c(p.val, "")
result$p <- c(ifelse(p.val < 0.001, "< 0.001", round(p.val,3)), "")
}else if(len >= 3){
formu <- as.formula(paste0(var, "~", "num"))
fit <- aov(formu, data = datexpr)
p.val <- summary(fit)[[1]]$'Pr(>F)'[1]
result$p.val <- c(p.val, rep("",len -1))
result$p <- c(ifelse(p.val < 0.001, "< 0.001", round(p.val,3)), rep("",len -1))
}
}else{
result <- datexpr %>% group_by(!!sym(group)) %>%
summarise(n = n(), median = median(!!sym(var), na.rm = T),
max = max(!!sym(var), na.rm = T),
min = min(!!sym(var), na.rm = T)) %>%
mutate(summarise = paste0(round(median, 3), "(", round(min, 3), "-",
round(max, 3), ")"),
category = group) %>%
select(category,level = group, n, summarise)
if(len == 2){
p.val <- wilcox.test(datexpr[[var]], datexpr[["num"]])$p.val
result$p.val <- c(p.val, "")
result$p <- c(ifelse(p.val < 0.001, "< 0.001", p.val), "")
}else if(len >= 3){
formu <- as.formula(paste0(var, "~", "num"))
fit <- kruskal.test(formu, data = datexpr)
p.val <- fit$p.value
result$p.val <- c(p.val, rep("",len -1))
result$p <- c(ifelse(p.val < 0.001, "< 0.001", round(p.val,3)), rep("",len -1))
}
}
return(result)
}
我们定了一个一个TableOneStat
函数。这个函数包括四个参数:
- dat : 需要分析的数据集
- group : 想要分析的分组
- var: 想要分析的连续性变量
- Normal: 是否服从正态分布
同时,有时候,数据集当中的不同分组也会包含缺失值。在函数当中也会先进行缺失值的删除的。
对于参数的统计结果,
- 如果服从正态分布,两个变量的我们使用
t检验
来进行分析。如果是2个以上变量的使用方差分析
。同时返回mean±sd
- 如果不服从正态分布:两个变量的我们使用
wilcox检验
来进行分析,如果是2个以上变量的使用kruskal检验
进行统计分析。同时返回median(min-max)
如果要分析一个连续性变量和一个分组的结果
TableOneStat(pbc, "status", "time")
## # A tibble: 3 x 6
## category level n summarise p.val p
##
## 1 status 0 232 2333.155±994.659 5.5382892506838e-19 < 0.001
## 2 status 1 25 1546.2±753.074 "" ""
## 3 status 2 161 1376.932±1049.228 "" ""
如果要分析一个连续性变量和分组的结果
result <- lapply(c("status", "trt", "sex", "stage"), function(x) TableOneStat(pbc, x, "time"))
result1 <- do.call(rbind, result)
result1
## # A tibble: 11 x 6
## category level n summarise p.val p
##
## 1 status 0 232 2333.155±994.659 5.5382892506838e-19 < 0.001
## 2 status 1 25 1546.2±753.074 "" ""
## 3 status 2 161 1376.932±1049.228 "" ""
## 4 trt 1 158 2015.62±1094.123 7.32884493240816e-99 < 0.001
## 5 trt 2 154 1996.864±1155.929 "" ""
## 6 sex m 44 1894.023±1213.034 6.03997896091397e-128 < 0.001
## 7 sex f 374 1920.578±1092.953 "" ""
## 8 stage 1 21 2654.81±1092.813 1.60762654134818e-14 < 0.001
## 9 stage 2 92 2389.837±1069.089 "" ""
## 10 stage 3 155 1997.452±973.838 "" ""
## 11 stage 4 144 1420.25±1040.369 "" ""