N'hésitez pas à le diffuser, sans oublier de citer la source.
Table 1 NoteBook
ATTENTION : pour faciliter la lecture de ce tutoriel, nous allons assumer que les conditions de validité des principaux tests (Chi2 et Student) sont respectés. Il vous faudra bien entendu les vérifier de votre côté.
Nous allons commencer par récupérer un dataframe sur Kaggle concernant le risque cardiovasculaire :
https://www.kaggle.com/yassinehamdaoui1/cardiovascular-disease/download/ds3WrBuyDewR9rMbNdTR%2Fversions%2FNWMwUpq65Kh9rqczUgk0%2Ffiles%2Fcardiovascular.txt
On va également installer les différents packages dont on aura besoin à savoir - tableOne - officer - flextable - magrittr
On ouvre le dataframe
setwd("~/destination")
Database <- read.table("cardiovascular.txt", header = TRUE, sep = ";")
str(Database)
## 'data.frame': 462 obs. of 11 variables:
## $ ind : int 1 2 3 4 5 6 7 8 9 10 ...
## $ sbp : int 160 144 118 170 134 132 142 114 114 132 ...
## $ tobacco : num 12 0.01 0.08 7.5 13.6 6.2 4.05 4.08 0 0 ...
## $ ldl : num 5.73 4.41 3.48 6.41 3.5 6.47 3.38 4.59 3.83 5.8 ...
## $ adiposity: num 23.1 28.6 32.3 38 27.8 ...
## $ famhist : Factor w/ 2 levels "Absent","Present": 2 1 2 2 2 2 1 2 2 2 ...
## $ typea : int 49 55 52 51 60 62 59 62 49 69 ...
## $ obesity : num 25.3 28.9 29.1 32 26 ...
## $ alcohol : num 97.2 2.06 3.81 24.26 57.34 ...
## $ age : int 52 63 46 58 49 45 38 58 29 53 ...
## $ chd : int 1 1 0 1 1 0 0 1 0 1 ...
On va supprimer la première colonne, qui est l’identifiant du patientDatabase = Database[,-1]
str(Database)
## 'data.frame': 462 obs. of 10 variables:
## $ sbp : int 160 144 118 170 134 132 142 114 114 132 ...
## $ tobacco : num 12 0.01 0.08 7.5 13.6 6.2 4.05 4.08 0 0 ...
## $ ldl : num 5.73 4.41 3.48 6.41 3.5 6.47 3.38 4.59 3.83 5.8 ...
## $ adiposity: num 23.1 28.6 32.3 38 27.8 ...
## $ famhist : Factor w/ 2 levels "Absent","Present": 2 1 2 2 2 2 1 2 2 2 ...
## $ typea : int 49 55 52 51 60 62 59 62 49 69 ...
## $ obesity : num 25.3 28.9 29.1 32 26 ...
## $ alcohol : num 97.2 2.06 3.81 24.26 57.34 ...
## $ age : int 52 63 46 58 49 45 38 58 29 53 ...
## $ chd : int 1 1 0 1 1 0 0 1 0 1 ...
On va également changer le tabac et l’obésité en variables binairesDatabase$tobacco = ifelse(Database$tobacco=="0","0","1")
Database$obesity = ifelse(Database$obesity<30,"0","1")
str(Database)
## 'data.frame': 462 obs. of 10 variables:
## $ sbp : int 160 144 118 170 134 132 142 114 114 132 ...
## $ tobacco : chr "1" "1" "1" "1" ...
## $ ldl : num 5.73 4.41 3.48 6.41 3.5 6.47 3.38 4.59 3.83 5.8 ...
## $ adiposity: num 23.1 28.6 32.3 38 27.8 ...
## $ famhist : Factor w/ 2 levels "Absent","Present": 2 1 2 2 2 2 1 2 2 2 ...
## $ typea : int 49 55 52 51 60 62 59 62 49 69 ...
## $ obesity : chr "0" "0" "0" "1" ...
## $ alcohol : num 97.2 2.06 3.81 24.26 57.34 ...
## $ age : int 52 63 46 58 49 45 38 58 29 53 ...
## $ chd : int 1 1 0 1 1 0 0 1 0 1 ...
On voit ici que nos variables factorielles ne sont pas sous formes de facteur On a plusieurs manières de procéder, mais on va faire ainsi :varsToFactor <- c("tobacco", "obesity", "chd")
Database[varsToFactor] <- lapply(Database[varsToFactor], factor)
str(Database)
## 'data.frame': 462 obs. of 10 variables:
## $ sbp : int 160 144 118 170 134 132 142 114 114 132 ...
## $ tobacco : Factor w/ 2 levels "0","1": 2 2 2 2 2 2 2 2 1 1 ...
## $ ldl : num 5.73 4.41 3.48 6.41 3.5 6.47 3.38 4.59 3.83 5.8 ...
## $ adiposity: num 23.1 28.6 32.3 38 27.8 ...
## $ famhist : Factor w/ 2 levels "Absent","Present": 2 1 2 2 2 2 1 2 2 2 ...
## $ typea : int 49 55 52 51 60 62 59 62 49 69 ...
## $ obesity : Factor w/ 2 levels "0","1": 1 1 1 2 1 2 1 1 1 2 ...
## $ alcohol : num 97.2 2.06 3.81 24.26 57.34 ...
## $ age : int 52 63 46 58 49 45 38 58 29 53 ...
## $ chd : Factor w/ 2 levels "0","1": 2 2 1 2 2 1 1 2 1 2 ...
On a fini de préparer les donnéesLa variable qui nous intéresse ici est “chd” à savoir maladie cardiovasculaire. On va créer une table 1 en s’intéressant à 2 groupes : antécédent familial oui/non
On va en profiter pour récupérer le nom de toutes nos variables
dput(names(Database))
## c("sbp", "tobacco", "ldl", "adiposity", "famhist", "typea", "obesity",
## "alcohol", "age", "chd")
On fait un copier coller de la réponse et on les mets dans un vecteur donc on aura besoin pour créer la table. On retire la variable de stratification (donc on ne met pas famhist)MyVars = c("sbp", "tobacco", "ldl", "adiposity", "typea", "obesity",
"alcohol", "age", "chd")
Pour faire cela on va faire en 3 étapes- On créé la table 1 globale
library(tableone)
tab1a <- CreateTableOne(vars = MyVars, data = Database)
tab1a <- print(tab1a, quote = FALSE, noSpaces = TRUE, printToggle = FALSE, showAllLevels = TRUE)
tab1a
##
## level Overall
## n "" "462"
## sbp (mean (SD)) "" "138.33 (20.50)"
## tobacco (%) "0" "107 (23.2)"
## "1" "355 (76.8)"
## ldl (mean (SD)) "" "4.74 (2.07)"
## adiposity (mean (SD)) "" "25.41 (7.78)"
## typea (mean (SD)) "" "53.10 (9.82)"
## obesity (%) "0" "389 (84.2)"
## "1" "73 (15.8)"
## alcohol (mean (SD)) "" "17.04 (24.48)"
## age (mean (SD)) "" "42.82 (14.61)"
## chd (%) "0" "302 (65.4)"
## "1" "160 (34.6)"
- On créée la table 1 par groupe
tab1b <- CreateTableOne(vars = MyVars, strata = "famhist", data = Database)
tab1b <- print(tab1b, quote = FALSE, noSpaces = TRUE, printToggle = FALSE, showAllLevels = TRUE)
tab1b
## Stratified by famhist
## level Absent Present p test
## n "" "270" "192" "" ""
## sbp (mean (SD)) "" "136.85 (20.58)" "140.41 (20.25)" "0.066" ""
## tobacco (%) "0" "74 (27.4)" "33 (17.2)" "0.014" ""
## "1" "196 (72.6)" "159 (82.8)" "" ""
## ldl (mean (SD)) "" "4.46 (2.03)" "5.14 (2.07)" "<0.001" ""
## adiposity (mean (SD)) "" "24.22 (7.89)" "27.08 (7.33)" "<0.001" ""
## typea (mean (SD)) "" "52.73 (9.94)" "53.62 (9.64)" "0.337" ""
## obesity (%) "0" "236 (87.4)" "153 (79.7)" "0.035" ""
## "1" "34 (12.6)" "39 (20.3)" "" ""
## alcohol (mean (SD)) "" "15.38 (21.62)" "19.38 (27.91)" "0.084" ""
## age (mean (SD)) "" "39.87 (15.30)" "46.96 (12.48)" "<0.001" ""
## chd (%) "0" "206 (76.3)" "96 (50.0)" "<0.001" ""
## "1" "64 (23.7)" "96 (50.0)" "" ""
- On va maintenant sortir une belle table Word
tab1f = cbind(as.data.frame(tab1a), as.data.frame(tab1b))
Ici on a créé un dataframe (car la fonction que l’on va utiliser prend un dataframe en argument) qui réunit les 2 tablesJe vous encourage à ouvrir le DataFrame avec la fonction :
View(tab1f)
On va faire quelques manipulations à savoir- On va retirer la colonne test qui ne sert à rien, et la seconde colonne level qui est redondante (on voit que ce sont les colonnes 3 et 7)
tab1f = tab1f[,-c(3,7)]
D’autre part, on voit que le nom des variables n’est pas une colonne à part entière, donc on va créer cette colonne (on en a besoin pour la suite)tab1f <- cbind(Variable = rownames(tab1f), tab1f)
On peut maintenant créer notre table (NB : un document Word temporaire va s’ouvrir, il lui manquera un peu de maquillage qu’il faudra faire à la main)library(officer)
library(flextable)
library(magrittr)
ft <- flextable(data = tab1f) %>%
autofit
tmp <- tempfile(fileext = ".docx")
read_docx() %>%
body_add_flextable(ft) %>%
print(target = tmp)
browseURL(tmp)
ft
Variable
|
level
|
Overall
|
Absent
|
Present
|
p
|
n
|
462
|
270
|
192
| ||
sbp..mean..SD..
|
138.33 (20.50)
|
136.85 (20.58)
|
140.41 (20.25)
|
0.066
| |
tobacco....
|
0
|
107 (23.2)
|
74 (27.4)
|
33 (17.2)
|
0.014
|
X
|
1
|
355 (76.8)
|
196 (72.6)
|
159 (82.8)
| |
ldl..mean..SD..
|
4.74 (2.07)
|
4.46 (2.03)
|
5.14 (2.07)
|
<0.001
| |
adiposity..mean..SD..
|
25.41 (7.78)
|
24.22 (7.89)
|
27.08 (7.33)
|
<0.001
| |
typea..mean..SD..
|
53.10 (9.82)
|
52.73 (9.94)
|
53.62 (9.64)
|
0.337
| |
obesity....
|
0
|
389 (84.2)
|
236 (87.4)
|
153 (79.7)
|
0.035
|
X.1
|
1
|
73 (15.8)
|
34 (12.6)
|
39 (20.3)
| |
alcohol..mean..SD..
|
17.04 (24.48)
|
15.38 (21.62)
|
19.38 (27.91)
|
0.084
| |
age..mean..SD..
|
42.82 (14.61)
|
39.87 (15.30)
|
46.96 (12.48)
|
<0.001
| |
chd....
|
0
|
302 (65.4)
|
206 (76.3)
|
96 (50.0)
|
<0.001
|
X.2
|
1
|
160 (34.6)
|
64 (23.7)
|
96 (50.0)
|