題記:我們?cè)谝郧暗奈恼轮薪榻B了競(jìng)爭(zhēng)風(fēng)險(xiǎn)模型的R語言實(shí)現(xiàn),今天我們與各位朋友分享如何基于競(jìng)爭(zhēng)風(fēng)險(xiǎn)模型繪制列線圖,以饗讀者。
1. 背景知識(shí)
在觀察某事件是否發(fā)生時(shí),如果該事件被其他事件阻礙,即存在所謂“競(jìng)爭(zhēng)風(fēng)險(xiǎn)”。研究中結(jié)局事件可能有多個(gè),某些結(jié)局將阻止感興趣事件的出現(xiàn)或影響其發(fā)生的概率,各結(jié)局事件形成“競(jìng)爭(zhēng)”關(guān)系,互為競(jìng)爭(zhēng)風(fēng)險(xiǎn)事件。
舉例來說,某研究人員收集了本市2007年確診為輕度認(rèn)知損害(MCI)的518例老年患者臨床資料,包括基本人口學(xué)特征、生活方式、體格檢查和合并疾病信息等,并于2010~2013年完成6次隨訪調(diào)查,主要觀察結(jié)局為發(fā)生阿爾茲海默?。ˋD)。隨訪期間,共發(fā)生AD78例,失訪84例,其中28例搬遷、31例退出、25例死亡。試問影響MCI向AD轉(zhuǎn)歸的因素都有哪些?本例中,如果MCI患者在觀察期間死于癌癥、心血管疾病、車禍等原因而未發(fā)生AD,就不能為AD的發(fā)病做出貢獻(xiàn),即死亡“競(jìng)爭(zhēng)”了AD的發(fā)生。傳統(tǒng)生存資料統(tǒng)計(jì)方法將發(fā)生AD前死亡的個(gè)體、失訪個(gè)體和未發(fā)生AD個(gè)體均按刪失數(shù)據(jù)(censored data)處理,可能會(huì)導(dǎo)致估計(jì)偏差[1]。對(duì)于死亡率較高的老年人群,當(dāng)有競(jìng)爭(zhēng)風(fēng)險(xiǎn)事件存在時(shí),采用傳統(tǒng)生存分析方法(K-M法、Cox比例風(fēng)險(xiǎn)回歸模型)會(huì)高估所研究疾病的發(fā)生風(fēng)險(xiǎn),產(chǎn)生競(jìng)爭(zhēng)風(fēng)險(xiǎn)偏倚,有人專門研究發(fā)現(xiàn)約46%的文獻(xiàn)可能存在這種偏倚。
本例中若選用競(jìng)爭(zhēng)風(fēng)險(xiǎn)模型處理較為恰當(dāng)。所謂競(jìng)爭(zhēng)風(fēng)險(xiǎn)模型(Competing Risk Model)是一種處理多種潛在結(jié)局生存數(shù)據(jù)的分析方法,早在1999年Fine和Gray就提出了部分分布的半?yún)?shù)比例風(fēng)險(xiǎn)模型,通常使用的終點(diǎn)指標(biāo)是累積發(fā)生率函數(shù)(Cumulative incidence function,CIF)[1-2]。本例中可以將發(fā)生AD前死亡作為AD的競(jìng)爭(zhēng)風(fēng)險(xiǎn)事件,采用競(jìng)爭(zhēng)風(fēng)險(xiǎn)模型進(jìn)行統(tǒng)計(jì)分析。競(jìng)爭(zhēng)風(fēng)險(xiǎn)的單因素分析常用來估計(jì)關(guān)心終點(diǎn)事件的發(fā)生率,多因素分析常用來探索預(yù)后影響因素及效應(yīng)值。
2. 案例分析
2.1 [案例分析]
本案例數(shù)據(jù)來自http://www.stat.unipg.it/luca/R/。有研究者探討骨髓移植對(duì)比血液移植治療白血病的療效,結(jié)局事件定義為“復(fù)發(fā)”,某些患者移植后不幸因?yàn)橐浦膊涣挤磻?yīng)死亡,那這些發(fā)生移植相關(guān)死亡的患者就無法觀察到“復(fù)發(fā)”的終點(diǎn),也就是說“移植相關(guān)死亡”與“復(fù)發(fā)”存在競(jìng)爭(zhēng)風(fēng)險(xiǎn)。故采用競(jìng)爭(zhēng)風(fēng)險(xiǎn)模型分析[3-4]。
首先從當(dāng)前工作路徑中導(dǎo)入數(shù)據(jù)文件’bmtcrr.csv’。
<pre style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">library(foreign)
bmt <-read.csv('bmtcrr.csv')
str(bmt)</pre>
<pre style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">## 'data.frame': 177 obs. of 7 variables:
$ Sex : Factor w/ 2 levels "F","M": 2 1 2 1 1 2 2 1 2 1 ...
$ D : Factor w/ 2 levels "ALL","AML": 1 2 1 1 1 1 1 1 1 1 ...
$ Phase : Factor w/ 4 levels "CR1","CR2","CR3",..: 4 2 3 2 2 4 1 1 1 4 ...
$ Age : int 48 23 7 26 36 17 7 17 26 8 ...
$ Status: int 2 1 0 2 2 2 0 2 0 1 ...
$ Source: Factor w/ 2 levels "BM+PB","PB": 1 1 1 1 1 1 1 1 1 1 ...
$ ftime : num 0.67 9.5 131.77 24.03 1.47 ...</pre>
這是一個(gè)數(shù)據(jù)框結(jié)構(gòu)的數(shù)據(jù),含有7個(gè)變量,共177個(gè)觀測(cè)。
$ Sex : 因子變量,2個(gè)水平:“F”,“M”。
$ D : 因子變量,2個(gè)水平:“ALL(急性淋巴細(xì)胞白血病)”,“AML(急性髓系細(xì)胞白血病)”。
$ Phase : 因子變量,4個(gè)水平:“CR1”,“CR2”,“CR3”,“Relapse”。
$ Age : 年齡。
$ Status: 結(jié)局,0=刪失,1=復(fù)發(fā),2=競(jìng)爭(zhēng)風(fēng)險(xiǎn)事件。
$ Source: 因子變量,2個(gè)水平:“BM+PB(骨髓移植+血液移植)”,“PB(血液移植)”。
$ ftime : 時(shí)間。
在R中加載競(jìng)爭(zhēng)風(fēng)險(xiǎn)模型的程輯包c(diǎn)mprsk,使用cuminc()函數(shù)及crr()函數(shù)即可進(jìn)行考慮競(jìng)爭(zhēng)風(fēng)險(xiǎn)事件生存資料的單因素分析與多因素分析,我們?cè)谇拔囊呀?jīng)詳細(xì)述及基于R語言實(shí)現(xiàn)的方式,此處不表。
如何對(duì)競(jìng)爭(zhēng)風(fēng)險(xiǎn)模型進(jìn)行可視化?如何繪制列線圖?
下面我們基于R演示如何繪制競(jìng)爭(zhēng)風(fēng)險(xiǎn)模型的列線圖。
首先,對(duì)數(shù)據(jù)集bmt中的變量進(jìn)行進(jìn)一步處理。
<pre style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">bmtage <- bmt
sex <- as.factor(ifelse(bmt
D <- as.factor(ifelse(bmt
phase_cr <- as.factor(ifelse(bmt
source = as.factor(ifelse(bmt$Source=='PB',1,0))</pre>
查看數(shù)據(jù)結(jié)構(gòu),并展示前6行。我們對(duì)數(shù)據(jù)集中的協(xié)變量重新進(jìn)行了賦值,并對(duì)多分類變量進(jìn)行了二值化。注意,此處多分類變量我們并未設(shè)置啞變量,主要考量是:在列線圖中如果出現(xiàn)啞變量的情形,結(jié)果解讀會(huì)讓人困惑,所以列線圖中應(yīng)避免啞變量的情形,可考慮根據(jù)專業(yè)知識(shí)將多分類變量按照等級(jí)資料處理或者二值化。
<pre style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">str(bmt)</pre>
<pre style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">## 'data.frame': 177 obs. of 12 variables:
$ Sex : Factor w/ 2 levels "F","M": 2 1 2 1 1 2 2 1 2 1 ...
$ D : Factor w/ 2 levels "0","1": 1 2 1 1 1 1 1 1 1 1 ...
$ Phase : Factor w/ 4 levels "CR1","CR2","CR3",..: 4 2 3 2 2 4 1 1 1 4 ...
$ Age : int 48 23 7 26 36 17 7 17 26 8 ...
$ Status : int 2 1 0 2 2 2 0 2 0 1 ...
$ Source : Factor w/ 2 levels "BM+PB","PB": 1 1 1 1 1 1 1 1 1 1 ...
$ ftime : num 0.67 9.5 131.77 24.03 1.47 ...
$ id : int 1 2 3 4 5 6 7 8 9 10 ...
$ age : int 48 23 7 26 36 17 7 17 26 8 ...
$ sex : Factor w/ 2 levels "0","1": 1 2 1 2 2 1 1 2 1 2 ...
$ phase_cr: Factor w/ 2 levels "0","1": 2 1 1 1 1 2 1 1 1 2 ...
$ source : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...</pre>
<pre style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">head(bmt)</pre>
<pre style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">## Sex D Phase Age Status Source ftime id age sex phase_cr source
1 M 0 Relapse 48 2 BM+PB 0.67 1 48 0 1 0
2 F 1 CR2 23 1 BM+PB 9.50 2 23 1 0 0
3 M 0 CR3 7 0 BM+PB 131.77 3 7 0 0 0
4 F 0 CR2 26 2 BM+PB 24.03 4 26 1 0 0
5 F 0 CR2 36 2 BM+PB 1.47 5 36 1 0 0
6 M 0 Relapse 17 2 BM+PB 2.23 6 17 0 1 0</pre>
regplot包中的regplot()函數(shù)可繪制較為美觀的nomogram。但是,它目前只接收coxph()、lm()和glm()函數(shù)返回的回歸對(duì)象。因此,為了繪制競(jìng)爭(zhēng)風(fēng)險(xiǎn)模型的nomogram,我們需要對(duì)原數(shù)據(jù)集加權(quán)創(chuàng)建一個(gè)新數(shù)據(jù)集用于為競(jìng)爭(zhēng)風(fēng)險(xiǎn)模型分析[5-6]。mstate包中的crprep()函數(shù)的功能主要在于創(chuàng)建此加權(quán)數(shù)據(jù)集,如下面的R代碼所示。然后,我們就可以使用coxph()函數(shù)對(duì)加權(quán)數(shù)據(jù)集進(jìn)行競(jìng)爭(zhēng)風(fēng)險(xiǎn)模型擬合,然后傳遞給regplot()來繪制nomogram。具體加權(quán)原理讀者可參考Geskus RB等人發(fā)表的文獻(xiàn)[5],此處不表。
下面,我們對(duì)原數(shù)據(jù)集bmt創(chuàng)建加權(quán)數(shù)據(jù)集并命名為df.w。其中,參數(shù)trans=指定需要加權(quán)計(jì)算的終點(diǎn)事件與競(jìng)爭(zhēng)風(fēng)險(xiǎn)事件;cens=指定截尾;id=傳入數(shù)據(jù)集bmt的id;keep=數(shù)據(jù)集中需要保留的協(xié)變量。
<pre style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">library(mstate)</pre>
<pre style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">## Loading required package: survival</pre>
<pre style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">df.w <- crprep("ftime", "Status",
data=bmt, trans=c(1,2),
cens=0, id="id",
keep=c("age","sex","D","phase_cr","source"))
df.wTstop - df.w$Tstart</pre>
上述代碼已經(jīng)創(chuàng)建一個(gè)加權(quán)數(shù)據(jù)集df.w,然后我們可以在此數(shù)據(jù)集上使用coxph()函數(shù)進(jìn)行競(jìng)爭(zhēng)風(fēng)險(xiǎn)分析。
<pre class="" style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">m.crr<- coxph(Surv(T,status==1)~age+sex+D+phase_cr+source,
data=df.w,
weight=weight.cens,
subset=failcode==1)
summary(m.crr)</pre>
<pre style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">## Call:
coxph(formula = Surv(T, status == 1) ~ age + sex + D + phase_cr +
source, data = df.w, weights = weight.cens, subset = failcode ==
1)
n= 686, number of events= 56
coef exp(coef) se(coef) z Pr(>|z|)
age -0.02174 0.97850 0.01172 -1.854 0.06376 .
sex1 -0.10551 0.89987 0.27981 -0.377 0.70612
D1 -0.53163 0.58764 0.29917 -1.777 0.07556 .
phase_cr1 1.06140 2.89040 0.27870 3.808 0.00014 ***
source1 1.06564 2.90269 0.53453 1.994 0.04620 *
---
Signif. codes: 0 '' 0.001 '' 0.01 '' 0.05 '.' 0.1 ' ' 1
exp(coef) exp(-coef) lower .95 upper .95
age 0.9785 1.0220 0.9563 1.001
sex1 0.8999 1.1113 0.5200 1.557
D1 0.5876 1.7017 0.3269 1.056
phase_cr1 2.8904 0.3460 1.6739 4.991
source1 2.9027 0.3445 1.0181 8.275
Concordance= 0.737 (se = 0.037 )
Likelihood ratio test= 28.33 on 5 df, p=3e-05
Wald test = 28.54 on 5 df, p=3e-05
Score (logrank) test = 30.49 on 5 df, p=1e-05</pre>
接下來,我們可以使用regplot()函數(shù)繪制nomogram。在nomogram中,將數(shù)據(jù)集中id=31的患者各協(xié)變量的取值映射到相應(yīng)的得分,并計(jì)算總得分,并分別計(jì)算其在36個(gè)月和60個(gè)月的累計(jì)復(fù)發(fā)概率,此概率即為控制了競(jìng)爭(zhēng)風(fēng)險(xiǎn)的累計(jì)復(fù)發(fā)概率,分別為:0.196和0.213。
<pre style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">library(regplot)
regplot(m.crr,observation=df.w[df.wfailcode==1,],
failtime = c(36, 60), prfail = T, droplines=T)</pre>
<pre style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">## Replicate weights assumed</pre>
<pre style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">## Click on graphic expected. To quit click Esc or press Esc</pre>
<pre style="box-sizing: inherit; border: 1px solid rgb(209, 209, 209); font-family: inherit; font-size: 16px; font-style: normal; margin: 0px 0px 5px; padding: 15px; vertical-align: baseline; line-height: 30.4px; max-width: 100%; overflow: auto; white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;"># $points.tables