文章目录

  • 前言
  • 一、table1
  • 二、简单制作
    • 1.一般过程(使用formula形式)
    • 2.发现问题
    • 3.端倪
    • 4.代码汇总
  • 总结

前言

之所以想发这个,想起来就气,上次因为数据库中病例数的变化(病例的纳入排除标准改变),导致多次统计分析,反复修改我的三线表,还有几次填错数据,还被老板骂,想起来就气,然后愤愤的把table1这个函数学习了一下,下次做三线表就很简单啦,开心。

三线表这部分我会分2-3部分写,今天写第一部分:主要是对三线表部分内容进行优化。下一次主要会讲添加P值,卡方值等列。

table1直接画出的三线表对于连续资料是将均值和中位值全部输出的,而不判定数据的正态性。
本文解决的问题:对于计量资料,分正态度分布和非正态分布,分别用mean(±sd)和median(min, max)这两种方法表示。这样我们还省去了做正态性检验的步骤。

先看下效果吧。注意看年龄和正态性数据哪一行那一行

如果你只是想用,直接跳到最后的代码总结部分,中间的内容可能更适合打破砂锅问到底的同志。


提示:关于table1中添加标题,表头,脚注我就不赘述,因为这部分对我们不重要。想了解的善用浏览器

一、table1

先了解一下这个函数画三线表的过程,姑且可以这样去理解。每次绘制一个交叉的格子时,如上图中红圈,函数会传入数据框中所有性别为男性的生存状态数据,然后取计算频数。下面某些过程可能会比较晦涩,欢迎大家在评论区提问或者私信。

二、简单制作

1.一般过程(使用formula形式)

其实这个table1中既可以放入formula格式(简单),也可以放入strata,labels的格式(灵活)。

代码如下(示例):

rm(list = ls())
library(table1)
library(survival)
options(stringsAsFactors = F)
a <- lung
str(a)#设置因子。需要注意,分类变量必须设置为因子或者字符串格式,否则它就把它当作数值进行计算了,这里,性别和生存状态都是分类变量。
a$sex <- factor(a$sex,levels = c(1,2),labels = c('男','女'))
a$status <- factor(a$status,levels = c(1,2),labels = c("存活","死亡"))#可以检验age是非正态的数据,这个p>0.1说明是正态,反之。
shapiro.test(a$age)$p.value#为了验证能否根据数据的正态性输出不同的格式,这里新增一组正态数据。
a$normdata <- rnorm(nrow(a),1,1)#设置缺失值,看函数是否能识别缺失数据
a$age[3] <- NA#设置单位,这样可以在行名那儿显示单位,如图中的(years,Kg)
units(a$age) <- 'year'
units(a$wt.loss) <- 'Kg'#设置标签,这里的标签就是行名。否则三线表行名会显示为status,age等等
label(a$status) <- "生存状态"
label(a$age) <- "年龄"
label(a$wt.loss) <- "体重减低"
label(a$sex) <- "性别"
label(a$normdata) <- "正态数据"
table1(~status+age+wt.loss+normdata|sex,data = a)

2.发现问题

运行完代码,确实出现了我们要的三线表,但发现了吗?不论我们的数据是否正态,他都会将均值(标准差)和中位数(极值)两种形式输出。这不是我们想要的。为了去删除,我们还要重新去进行正态性检验然后一行一行删除,显然这不是我们学习R语言的初衷。

3.端倪

抛开这个问题先不谈,我们先学习一下,如何改变这个三线表?
看一下帮助文档,我已经为大家探索好了,这里表格中的数据是通过render参数传递的。
render指向一个render.default函数,render.default中包含了传递连续型变量、分类变量、空值的传递,是函数的形式。调出这两个函数的代码看一下。

从函数可以发现分类变量和数值变量的表现形式(红色框标记)。

这里我重写这个render函数和render.continuous.default函数就初步实现函数根据正态检验选择性输出。

代码如下(示例):

重写render.default函数
rd <- function(x, name, ...){#这里传入的参数x和name
#举个例子,当绘制男性,age这个格子的时候(一下所有的例子都是这个),x就是:数据中性别为男性的所有年龄数据。name就是age,那么这里的a[[name]]用来提取数据a中年龄数据(男性女性都包括)y <- a[[name]]
#判断年龄数据中是否存在空值,如果是空值,我们要加入missing行m = any(is.na(y))
#根据传入的数据是否是数值分别处理if (is.numeric(y)) {#判断是否正态,并将判断的结果传入my.render.cont函数中normt=(shapiro.test(y)$p.value>0.1)+2my.render.cont(x,n=normt,m=m,...)}else{#因为分类变量我们不需要处理,这里直接调用默认的函数就行了render.default(x=x, name=name, ...)}}#重写render.continuous.default函数。
my.render.cont <- function (x,n,m, ...) {#x和上面函数中的意义一样,n是判断是否正态的结果,m是判断是否空值的结果a=with(stats.apply.rounding(stats.default(x, ...), ...), c("", `Mean (±SD)` = sprintf("%s (±%s)", MEAN, SD),`Median (Min, Max)` = sprintf("%s (%s, %s)", MEDIAN, MIN, MAX)))[-n] #根据正态判断结果判定输出均值还是中位数if (m) {a <- c(a,with(stats.apply.rounding(stats.default(is.na(x), ...), ...)$Yes,c(`Missing` = sprintf("%s (%s%%)", FREQ, PCT))))#这里就是根据是否存在空值输出missing行}a
}###最后的最后就是运行我们的绘制三线表函数,render参数和render.continuous参数换成我们重写的函数。
table1(~status+age+wt.loss+normdata|sex,data = a,render = rd,render.continuous=my.render.cont)


出图,完美,可以发现正态性的数据和非正态性的数据展现形式是不一样的。

4.代码汇总

最后的最后当然是要把代码汇总,方便你们享用啦

rm(list = ls())
library(survival)
library(survminer)
library(table1)
options(stringsAsFactors = F)
#重写函数
rd <- function(x, name, ...){y <- a[[name]]m = any(is.na(y))if (is.numeric(y)) {normt=(shapiro.test(y)$p.value>0.1)+2my.render.cont(x,n=normt,m=m,...)}else{render.default(x=x, name=name, ...)}}#重写连续变量处理函数
my.render.cont <- function (x,n,m, ...) {a=with(stats.apply.rounding(stats.default(x, ...), ...), c("", `Mean (±SD)` = sprintf("%s (±%s)", MEAN, SD),`Median (Min, Max)` = sprintf("%s (%s, %s)", MEDIAN, MIN, MAX)))[-n]if (m) {a <- c(a,with(stats.apply.rounding(stats.default(is.na(x), ...), ...)$Yes,c(`Missing` = sprintf("%s (%s%%)", FREQ, PCT))))}a
}
#########################分界线#############################################
####上面的部分是可以重复使用的不用变,以下部分需要你换成自己的数据并更改部分内容
############################################################################
a <- lung
str(a)#设置因子、以年龄、性别、体重减低、状态为例子
a$sex <- factor(a$sex,levels = c(1,2),labels = c('男','女'))
a$status <- factor(a$status,levels = c(1,2),labels = c("存活","死亡"))
a$normdata <- rnorm(nrow(a),1,1)
a$age[3] <- NA#设置单位
units(a$age) <- 'year'
units(a$wt.loss) <- 'Kg'#设置标签
label(a$status) <- "生存状态"
label(a$age) <- "年龄"
label(a$wt.loss) <- "体重减低"
label(a$sex) <- "性别"
label(a$normdata) <- "正态数据"
table1(~status+age+wt.loss+normdata|sex,data = a)
table1(~status+age+wt.loss+normdata|sex,data = a,render = rd,render.continuous=my.render.cont)
##两相对比,你更喜欢哪一个呢?

总结

其实之前就看过这个函数,但是当时只是玩玩的心态,学了个一知半解,这次真的是痛定思痛想要搞定它。
预告:下一篇就是添加卡方检验和t检验的p值
本人还是初学者,如有错误,欢迎批评指正,虚心接受大家的建议。

R语言:三线表(1)相关推荐

  1. 关于R语言和社交网络分析的几篇文章

    [转载]初学社交网络分析-<庶民的微胜利:R与社交网络分析> 关键词:igraph 图表输出 图形优化 初次尝试igraph包 igraph包入门 R语言画社交关系图 根据用户分享的歌曲, ...

  2. oracle矩阵函数,R语言矩阵matrix函数

    矩阵是元素布置成二维矩形布局的R对象. 它们包含相同原子类型的元素.尽管我们可以创建只包含字符或只逻辑值的矩阵,但是它们没有多大用处.我们使用的是在数学计算中含有数字元素矩阵. 使用 matrix() ...

  3. 三线表是什么?R语言使用table1包绘制(生成)三线表、构建不分层的三线表

    三线表是什么?R语言使用table1包绘制(生成)三线表.构建不分层的三线表 目录

  4. R语言使用table1包绘制(生成)三线表、使用单变量分列构建三线表、编写自定义函数在三线表中添加p值

    R语言使用table1包绘制(生成)三线表.使用单变量分列构建三线表.编写自定义函数在三线表中添加p值 目录

  5. R语言使用table1包绘制(生成)三线表、使用单变量分列构建三线表、设置transpose参数转置三线表、变量作为列,子组(strata)作为行

    R语言使用table1包绘制(生成)三线表.使用单变量分列构建三线表.设置transpose参数转置三线表.变量作为列,子组(strata)作为行 目录

  6. R语言使用table1包绘制(生成)三线表、使用单变量分列构建三线表、自定义overall的标签名称

    R语言使用table1包绘制(生成)三线表.使用单变量分列构建三线表.自定义overall的标签名称 目录

  7. R语言使用table1包绘制(生成)三线表、使用单变量分列构建三线表、为指定变量添加单位信息、自定义overall的标签名称

    R语言使用table1包绘制(生成)三线表.使用单变量分列构建三线表.为指定变量添加单位信息.自定义overall的标签名称 目录

  8. R语言使用table1包绘制(生成)三线表、使用单变量分列构建三线表、编写自定义三线表结构(将因子变量细粒度化重新构建三线图)、为不同的变量显示不同的统计信息

    R语言使用table1包绘制(生成)三线表.使用单变量分列构建三线表.编写自定义三线表结构(将因子变量细粒度化重新构建三线图).为不同的变量显示不同的统计信息 目录

  9. 三线表是什么?R语言使用table1包绘制(生成)三线表、使用单变量分列构建三线表、通过topclass参数自定义三线表表格的显示形式(显示为类似斑马线、并将所有列居中,包括包含行标签的第一列)

    三线表是什么?R语言使用table1包绘制(生成)三线表.使用单变量分列构建三线表.通过topclass参数自定义三线表表格的显示形式(显示为类似斑马线.并将所有列居中,包括包含行标签的第一列) 目录

  10. 三线表是什么?R语言使用table1包绘制(生成)三线表、使用单变量分列构建三线表、编写自定义三线表结构(将因子变量细粒度化重新构建三线图)、编写自定义函数在三线表中添加p值

    三线表是什么?R语言使用table1包绘制(生成)三线表.使用单变量分列构建三线表.编写自定义三线表结构(将因子变量细粒度化重新构建三线图).编写自定义函数在三线表中添加p值 目录

最新文章

  1. java whois_Java如何实现简单的whois查询
  2. ***S 2012 交互式报表 -- 钻取式报表
  3. sql like 多条件
  4. Linux 服务器高并发调优实战
  5. Vuex 源码还有一些缺陷?
  6. Java 阶段面试 知识点合集 - 我们到底能走多远系列(15)
  7. springContext
  8. Brackets(POJ-2955)
  9. ORA-04031错误分析和解决
  10. 微积分:2.2泰勒公式函数极值定积分
  11. 重视“互联网+政务服务”改革工作 推进智慧城市建设
  12. App ID申请(将项目中的ID向苹果申请)
  13. 给PPT插入页码和总页码
  14. 2021年茶艺师(初级)模拟考试及茶艺师(初级)模拟考试题
  15. 优酷上线优酷号短视频自媒体平台!
  16. 桂电的计算机专业研究生录取比例,桂电研究生就业待遇 桂林电子科技大学就业率...
  17. vue组件中数据共享——vuex
  18. 自动化测试 | 如何选择半导体测试系统——你不得不知道的事
  19. t3怎么设置远程服务器,T1怎么配置才能让客户端远程登录上服务器呢?不借助任何第三方工具。...
  20. String.hashCode() 31?

热门文章

  1. IGF1重组人胰岛素样生长因子-1解决方案
  2. 89.77%准确率!谷歌大脑提出CoAtNet:结合卷积和注意力
  3. 南京长江隧道发生连环追尾事故 没有人员伤亡-南京-隧道-追尾
  4. Chino with Equation 不定方程
  5. Error: Run Generate Functional Simulation Netlist
  6. 编写C# Windows服务,用于杀死Zsd.exe进程
  7. 标自然段的序号格式_正确的序号及标点使用格式
  8. about GLOBAL TEMPORARY TABLES
  9. 什么是元组以及元组的作用
  10. 区块链+:颠覆互联网+模式不是事!