• R生成三线表



    主要基于table1 或tableone 包

    table1包

    测试数据生成

    data=data.frame(
      性别=sample(c("男","女"), 1000,replace=T),
      年龄=round(rnorm(1000,50, 15)),
      民族= sample(c("汉族","壮族","其他"),1000,replace=T),
      身高= round(rnorm(1000,170, 5)),
      体重= round(rnorm(1000,75, 5)),
      收缩压= round(rnorm(1000,130, 15)),
      舒张压= round(rnorm(1000,90, 5)),
      身体状况= sample(c("优","中","差"), 1000,replace=T),
      高血压= sample(c("是","否"), 1000,replace=T),
      吸烟= sample(c("是","否"), 1000,replace=T),
      喝酒= sample(c("是","否"), 1000,replace=T)
    )
    head(data)
    
    #运行内容
      性别 年龄 民族 身高 体重 收缩压 舒张压 身体状况 高血压 吸烟 喝酒
    165 壮族  176   67    149     82       差     否   否   否
    284 其他  177   73    137     92       差     是   是   是
    375 其他  168   82    111     90       优     是   是   否
    467 其他  171   76    152     93       差     是   是   否
    567 壮族  172   73    118     83       优     否   否   是
    644 壮族  168   82    141     83       优     是   否   是
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    制作三线表

    基本三线表, 分类变量默认以 例数(占比%),连续变量以均数(标准差)或者中位数[最小、最大]表示

    pacman::p_load(table1) #加载table1包
    
    # ~ 后面接需要统计描述的列,| 表示分组
    # 按是否患有高血压分组统计 性别、年龄、民族、身高情况
    table1(~性别+年龄+民族+身高|高血压,data = data)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    考虑统计检验(卡方检验、t检验)

    #———————————————————————————————————————————— 定义检验函数
    # 这两个主要是实现卡方检验和t检验,若是需要用到非参数检验、方差分析需要自己定义
    pvalue <- function(x, ...) {
      y <- unlist(x)
      g <- factor(rep(1:length(x), times=sapply(x, length)))
    
      if (is.numeric(y)) {
        # 数值型数据用t-test(两组比较)
        p <- t.test(y ~ g)$p.value                          
         } else {
        # 因子型数据用卡方
        p <- chisq.test(xtabs(~y+ g))$p.value                
         }
      c("", sub("<", "<", format.pval(p, digits=3, eps=0.001)))
      
    }
    
    statistic <- function(x, ...) {
      y <- unlist(x)
      g <- factor(rep(1:length(x), times=sapply(x, length)))
    
      if (is.numeric(y)) {
       
       statistic <- t.test(y ~ g)$statistic
      } else {
       
      statistic <- chisq.test(xtabs(~y+ g))$statistic
          }
      c("",round(statistic,3))
    }
    
    #———————————————————————————————————————————— 三线表
    # 输出带有统计检验的三线表
    # 分别比较是否患有高血压两组之间所有特征的差异~
    table1(~.|高血压,data = data, extra.col=list( 'statistic'=statistic,'P-value'=pvalue), overall=F)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    在这里插入图片描述
    table1输出的结果格式是html格式的,可用浏览器打开,然后复制到word或者excel中。也直接导出保存为csv格式,导出时格式可能略微有点不同。

    out=table1(~.|高血压,data = data, extra.col=list( 'statistic'=statistic,'P-value'=pvalue), overall=F)
    write.csv(out, "d:/out.csv",row.names = F)
    
    • 1
    • 2

    Tableone包

    加载包 探索数据类型

    pacman::p_load(tableone)#1.加载R包
    rm(list = ls()) #2.清理运行环境
    str(data)   #3.查看数据数据性质
    names(data) #4.提取变量的名字
    
    #运行内容
    'data.frame':	1000 obs. of  11 variables:
     $ 性别    : chr  "女" "女" "男" "男" ...
     $ 年龄    : num  65 84 75 67 67 44 50 64 44 47 ...
     $ 民族    : chr  "壮族" "其他" "其他" "其他" ...
     $ 身高    : num  176 177 168 171 172 168 169 165 164 163 ...
     $ 体重    : num  67 73 82 76 73 82 82 79 69 83 ...
     $ 收缩压  : num  149 137 111 152 118 141 131 118 123 135 ...
     $ 舒张压  : num  82 92 90 93 83 83 90 91 91 91 ...
     $ 身体状况: chr  "差" "差" "优" "差" ...
     $ 高血压  : chr  "否" "是" "是" "是" ...
     $ 吸烟    : chr  "否" "是" "是" "是" ...
     $ 喝酒    : chr  "否" "是" "否" "否" ...
     > names(data) #4.提取变量的名字
     [1] "性别"     "年龄"     "民族"     "身高"     "体重"     "收缩压"   "舒张压"   "身体状况" "高血压"   "吸烟"     "喝酒" 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    数据整理分类

    myVars的()中输入想要在Table 1出现的变量

    myVars <- c("性别","年龄","民族","身高", 
                "体重","收缩压", "舒张压","身体状况","高血压", 
                "吸烟","喝酒") 
    
    • 1
    • 2
    • 3

    catVars的()内指明上述中哪些是分类变量

    catVars <- c("性别","民族","身体状况","高血压", 
                  "吸烟","喝酒") 
    
    • 1
    • 2

    指定非正态分布连续变量变量

     nonvar <- c("收缩压","舒张压")  #此为举例
    
    • 1

    假如有T<5变量应使用Fisher精确检验,本文数量大,无需Fisher精确检验

     exactvars <- c("a", "b")  #此为举例
    
    • 1

    catDigits = 2, contDigits = 3, pDigits = 4,修改连续变量小数位数为2位,分类变量百分比位数为3位,调整小数位数为4位;

    构建Table函数

     table <- CreateTableOne(vars = myVars, #条件1
                           factorVars = catVars,#条件2
                           strata = "高血压", #条件4 用于分为两个类别
                            data = data, #原始数据
                         addOverall = TRUE  );table#条件6加入overall
      
     table1<- print(table, #构建的table函数(带条件1.2.3)
                     nonnormal = nonvar,#条件4
                     #exact = exactvars,#条件5
                     catDigits = 2,contDigits = 3,pDigits = 4, #附加条件
    
                     showAllLevels=TRUE, #显示所有变量
                     quote = FALSE, # 不显示引号
                     noSpaces = TRUE, # #删除用于对齐的空格
                     printToggle = TRUE) #展示输出结果  
                     
     write.csv(table1, "E:/Rworkplace//table1.csv",row.names = F)                   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    Tableone函数细节

    table <- CreateTableOne(
      vars, #指定哪些变量是Table 1需要汇总的变量
      strata,#指定进行分类的变量,不写则只出Overall列
      data,# 变量的数据集名称
      factorVars,#指定哪些变量为分类变量,指定的变量应是vars参数中的变量
      includeNA = FALSE,#为TRUE则将缺失值作为因子处理,仅对分类变量有效
      test = TRUE,#默认为TRUE,当有2个或多个组时,自动进行组间比较
      testApprox = chisq.test,#默认卡方检验
      argsApprox = list(correct = TRUE),# 进行连续校正的chisq.test
      testExact = fisher.test,#进行fisher精确检验
      argsExact = list(workspace = 2 * 10^5),# 指定fisher.test分配的内存空间
      testNormal = oneway.test, # 连续变量为正态分布进行的检验,默认为oneway.test,两组时相当于t检验
      argsNormal = list(var.equal = TRUE), # 假设为等方差分析
      testNonNormal = kruskal.test,# 默认为Kruskal-Wallis秩和检验
      argsNonNormal = list(NULL),#传递给testNonNormal中指定的函数的参数的命名列表
      smd = TRUE,#如果为TRUE(如默认值)并且有两个以上的组,则将计算所有成对比较的标准化均值差。
      addOverall = FALSE#仅在分组时使用)将整个列添加到表中。Smd和p值计算仅使用分层的列阵进行。
    );table
    
    table1<- print(
      x, #CreateTableOne()的 <- 前的名字(x=table)
      catDigits = 1, #连续变量小数位1位
      contDigits = 2,#分类变量保留2位
      pDigits = 3,#p值保留3位
      quote = FALSE,#默认值为FALSE。如果为TRUE
                    #,则包括行名和列名在内的所有内容都用引号引起来,以便您可以轻松地将其复制到Excel。
      missing = FALSE,#是否显示丢失的数据信息
      explain = TRUE,#显示百分比时是否在变量名称中添加解释,即(%)添加到变量名称中。
      printToggle = TRUE,#如果为FALSE,则不输出
      test = TRUE,#是否显示p值。默认为TRUE。
      smd = FALSE,#是否显示标准化均值差异。默认为FALSE。如果存在多个对比,则显示所有可能的标准化均值差的平均值。
      noSpaces = FALSE,#是否删除为对齐而添加的空格。
      padColnames = FALSE,#是否用空格填充列名以居中对齐。默认值为FALSE。如果noSpaces = TRUE,则不进行
      varLabels = FALSE,#是否用从labelled :: var_label()函数获得的变量标签替换变量名。
      format = c("fp", "f", "p", "pf")[1],#默认值为“ fp”频率(百分比)。您也可以选择仅“ f”频率,“仅p”百分比和“ pf”百分比(频率)。
      showAllLevels = FALSE,#是否显示所有级别。
      cramVars = NULL,#字符向量,用于指定两个级别的分类变量,对于这两个级别的变量,应在一行中显示两个级别。
      dropEqual = FALSE,#是否删除“ =第二级名称”描述,指示为两级分类变量显示哪个级别。
      exact = NULL,#字符向量,用于指定p值应为精确测试值的变量。
      nonnormal = NULL,#字符向量,用于指定p值应为非参数检验的变量的变量。
      minMax = FALSE#对于非正态变量,是否使用[min,max]而不是[p25,p75]。默认值为FALSE。
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    相比之下 table1包输出的html格式的表格更为简洁 好看

    参考两篇公众号文章:
    1.你的时间应该用在更重要的事情上–table1
    2.R语言|4. 轻松绘制临床基线表Table 1

  • 相关阅读:
    ceph 分布式存储与部署
    Python(四)——变量的定义和简单使用
    merge into 更新和插入
    RabbitMQ 入门系列:8、扩展内容:接收信息时:可否根据RoutingKey过滤监听信息,答案是不能。
    计算机毕业设计Python+djang的新生报到服务管理系统(源码+系统+mysql数据库+Lw文档)
    酷雷曼第二期无人机技能培训圆满举办
    vue2和vue3中好用的数据重置方法
    Matter 协议系列:发现
    Js实现前端分页器
    解决MySQL数据库拒绝远程计算机连接问题
  • 原文地址:https://blog.csdn.net/leeningzzu/article/details/127904696