R教程:如何通過cox回歸模型計算RD(危險差)和NNT?

2021-03-02 醫咖會

RD:risk difference,危險差,指的是幹預組與對照組相比,危險減少或增加的絕對值,即RD=Prtreated - Pruntreated;

NNT/H:number needed to treat/harm,當我們研究保護性因素時,即Prtreated < Pruntreated時,常常報導NNT,指的是為了避免一例結局事件的發生,平均多少個人需要接受有利治療;當我們研究危險性因素時,即Prtreated > Pruntreated時,常常報導NNH,指的是為了誘發一例結局事件的發生,平均多少人需要接受有害治療。

 

綜上,NNT/H=1÷abs(RD),當RD<0時,為NNT,當RD>0時,為NNH。

 

在生存分析中為什麼要報導 RD 和 NNT/H,僅僅報導HR(hazard ratio, 風險比)不夠嗎?

 

在回答這個問題之前,我們可以將流行病學中常見的效應值分為兩大類:

一類是相對效應值,如risk ratio,odds ratio和hazard ratio,表示的是與對照組相比,治療組效應減少或增加的相對值;

 

另一個是絕對效應值,如risk difference,表示的是與對照組相比,治療組效應減少或增加的絕對值。與相對效應值相比,絕對效應值更具有臨床意義。(詳見:總結:那些可以評價幹預措施效果的指標們)

 

舉例來說,某種新藥的隨機對照試驗得到該藥與安慰劑相比HR為0.5,顯示出該藥可以顯著降低結局事件的發生率。但是,當結局事件在安慰劑組的發生率為1%和50%時,HR等於0.5對於臨床實踐而言意義卻完全不一樣。

 

假設結局事件為皮疹,當結局事件在安慰劑組的發生率為1%,結局事件本身發生率不高且不嚴重,該藥物與安慰劑相比降低了0.5%的結局事件發生率,降低有限,所以該藥物臨床意義不大;

當結局事件在安慰劑組的發生率為50%,結局事件本身發生率很高雖不嚴重,該藥物與安慰劑相比降低了25%的結局事件發生率,降低顯著,所以該藥物臨床意義較大。

 

那麼,怎麼計算生存數據中的 RD 和 NNT/H 呢?

 

在生存數據中,

 

通過上式,我們可以看到要求 RD 和 NNT/H 的關鍵在於求得Prtreated(T<t)和Pruntreated(T<t)。

 

為此我們先回顧一下生存分析中各個函數之間的關係

 

假設T是一個大於0的隨機變量,表示從隨訪開始到結局事件發生的時間,T的概率密度函數(probability density function, p.d.f.)為,累積分布函數(cumulative distribution function, c.d.f.)為

 

生存函數survival function定義如下

風險函數hazard function定義如下

即:

一般我們設,叫做累計風險函數cumulative hazard function,因此上式可以寫成

基於以上式子,

 

通過cox回歸,我們可以得到α和β的估計值,為了求得上式,我們就需要知道S0(t)和Pr(X),顯然Pr(X)是未知的,問題到這裡似乎無解了,但是我們不妨變換一下思路,

為了求得此式,我們需要知道,因為所有人在Zi=0和Xi=0時,基線生存函數均一致,因此題就簡化為求S0(t)了,通過cox回歸模型求S0(t)常見的方法有兩種,分別為 Breslow『s estimator 和 Kalbfleish & Prentice estimator,這裡就不詳細介紹了,感興趣的讀者可以自行閱讀。

 

基於上述過程,我們可以得到通過cox回歸模型計算 RD 和 NNT/H 的方法

1. 擬合cox回歸模型;

2. 生成治療數據集,即所有人均接受治療,設treatment=1,其他協變量取值與原始數據集一致;

3. 生成對照數據集,即所有人均不接受治療,設treatment=0,其他協變量取值與原始數據集一致;

4. 指定 RD 和 NNT/H 的預測時間點,即在那些隨訪時間點上計算 RD 和NNT/H;

5. 在治療數據集上預測每個患者在設定的時間點上的生存概率;

6. 在對照數據集上預測每個患者在設定的時間點上的生存概率;

7. 計算治療數據集上所有人在設定的時間點上的生存概率的均值;

8. 計算對照數據集上所有人在設定的時間點上的生存概率的均值;

9. 將兩組均值做差得到在設定的時間點上的RD值,將RD值取倒數得到在設定的時間點上的NNT/H;

10. 用bootstrap的方法求得RD和NNT/H的置信區間。

 

上述過程的R代碼如下:

## import packages

library(rms)

library(withr)

library(dplyr)

library(doParallel)

 

## set cores

cl <- makeCluster(3)

registerDoParallel(cl)

 

## define functions

inverse.logit <- function(x) {

  return(exp(x) / (1 + exp(x)))

}

RD_NNT.H.cal <- function(data, times, treatment, formula) {

  data.treated <- data

  data.treated[ , treatment] <- 1

  data.untreated <- data

  data.untreated[ , treatment] <- 0

  cox.res <- cph(formula, data, surv = T, x = T, y = T)

  treated.sur <- survest(cox.res, newdata = data.treated, times = time) 

  untreated.sur <- survest(cox.res, newdata = data.untreated, times = time)

  treated.Mean <- colMeans(1 - treated.sur$surv) 

  untreated.Mean <- colMeans(1 - untreated.sur$surv)

  RD <- treated.Mean - untreated.Mean

  type <- ifelse(RD >= 0, 'NNH', 'NNT')

  NNT.H <- 1 / abs(RD)

  return(data.frame(time = time, RD = RD, type = type, NNT.H = NNT.H))

}

 

## generate survival data

set.seed(20190401)

n = 1000

alpha0 = log(1)

alpha1 = log(3)

beta0 = log(1)

beta1 = log(3)

beta2 = log(4)

 

X <- rbinom(n, 1, 0.5)

E <- rbinom(n, 1, inverse.logit(alpha0 + alpha1 * X))

Ytime <- rexp(n, rate = exp(beta0 + beta1 * X + beta2 * E))

Ctime <- runif(n, min = 3, max = 6)

Time <- ifelse(Ytime <= Ctime, Ytime, Ctime)

Status <- ifelse(Ytime <= Ctime, 1, 0)

dta <- data.frame(X, E, Time, Status)

 

## calculate NNH

time <- seq(1, 4, length.out = 20)

res.pe <- RD_NNT.H.cal(dta, time, 'E', Surv(Time, Status) ~ X + E)

 

## caculate the CIs

res.CI <- foreach (i = 1 : 1000, 

                   .packages = c('dplyr', 'rms', 'withr'), 

                   .combine = 'rbind') %dopar% {

  with_seed(i, dta.sample <- dta %>% sample_frac(1, replace = T))

  res <- RD_NNT.H.cal(dta.sample, time, 'E', Surv(Time, Status) ~ X + E)

}

res.CI <- res.CI %>% 

  group_by(time) %>% 

  summarise(RD.p2.5 = quantile(RD, 0.025), 

            RD.p97.5 = quantile(RD, 0.975), 

            NNT.H.p2.5 = quantile(NNT.H, 0.025), 

            NNT.H.p97.5 = quantile(NNT.H, 0.975))

 

## combine results

res <- merge(res.pe, res.CI, by = 'time') %>% 

  select(time, type, RD, RD.p2.5, RD.p97.5, NNT.H, NNT.H.p2.5, NNT.H.p97.5)

 

上述代碼運行結果如下:

 

醫咖會微信:medieco-ykh

關注醫咖會,提高臨床研究水平!

快加小咖個人微信(xys2018ykf),拉你進統計討論群和眾多熱愛研究的小夥伴們一起交流學習。

點擊左下角「閱讀原文」,看看醫咖會既往推送了哪些統計教程。或者使用電腦打開網址:http://www.mediecogroup.com/,查看70種SPSS教程。

相關焦點

  • 用R進行Lasso regression回歸分析
    glmnet是由史丹福大學的統計學家們開發的一款R包,用於在傳統的廣義線性回歸模型的基礎上添加正則項,以有效解決過擬合的問題,支持線性回歸,邏輯回歸,泊松回歸,cox回歸等多種回歸模型,連結如下https://cran.r-project.org/web/packages/glmnet/index.html對於正則化,提供了以下3種正則化的方式
  • 基於R的生存資料預測模型構建與Nomogram繪製
    我們可以通過Cox回歸等方法先構建一個數學模型,然後把這個模型可視化為Nomogram,通過圖形來計算每個具體患者的生存概率。Nomogram中文常稱為諾莫圖或者列線圖,其本質就是回歸方程的可視化。它根據所有自變量標準回歸係數的大小來制定評分標準,給每個自變量的每種取值水平一個評分,對每個患者,就可計算得到一個總分,再通過得分與結局發生概率之間的轉換函數來計算每個患者的結局時間發生的概率。
  • r語言一元回歸模型專題及常見問題 - CSDN
    計算模型的參數k和b(1)估算參數k和b的典型值(k<-cov(cost,sales)/cov(cost,cost))#模型參數k(b<-mean(sales)-k*mean(cost))        #模型參數b也可使用回歸方程建立函數lm來計算。
  • R語言——交叉驗證法計算線性回歸模型擬合優度的第三種R方
    想來想去,今天就寫一篇和R語言有關的,畢竟不能忘記初心呀!凡是學過計量的同學,哪怕只記得一點點皮毛,對於R方和調整R方也應該是再熟悉不過了。R方和調整R方是判斷回歸模型擬合度的最為方便簡單的指標,一般來說,數值越大代表模型的擬合度越好。R方的缺點很明顯,當我們在回歸模型中加入更多的回歸自變量時,不管這個回歸自變量能否解釋因變量,R方都會增加。為了克服這個缺點,引入了調整R方。
  • R語言實現LASSO回歸模型
    我們知道廣義線性模型包括了一維連續因變量、多維連續因變量、非負次數因變量、二元離散因變量、多元離散因變等的回歸模型。然而LASSO對以上的數據類型都適合,也可以說LASSO 回歸的特點是在擬合廣義線性模型的同時進行變量篩選(variable selection)和複雜度調整(regularization)。
  • 回歸標準差的計算公式 - CSDN
    可以通過選擇View/Covariance Matrix項來察看整個協方差矩陣。(3)t-統計量t統計量是由係數估計值和標準差之間的比率來計算,它是用來檢驗係數為零的假設的。(3)回歸標準差回歸標準差是在殘差的方差的估計值基礎之上的一個總結。計算方法如下:
  • 正態分布 線性回歸 - CSDN
    採用最小二乘法進行線性回歸時,需要滿足特定的條件:正態性:一定範圍內,給定任意x值,對應的y均服從正態分布獨立:即誤差項間不存在相關,一般時間序列數據會存在自相關線性:因變量和自變量有線性關係同方差性:即模型誤差項的方差相等。
  • r語言 多元回歸模型_r語言多元回歸模型殘差分析 - CSDN
    1、多元線性回歸模型1.1多元回歸模型與多元回歸方程設因變量為y,k個自變量分別為,描述因變量y如何依賴於自變量和誤差項ε的方程稱為多元回歸模型。其一般形式可表示為:式中,為模型的參數,ε為隨機誤差項。
  • 回歸、分類與聚類:三大方向剖解機器學習算法的優缺點(附Python和R...
    在實踐中,簡單的線性回歸通常被使用正則化的回歸方法(LASSO、Ridge 和 Elastic-Net)所代替。正則化其實就是一種對過多回歸係數採取懲罰以減少過擬合風險的技術。當然,我們還得確定懲罰強度以讓模型在欠擬合和過擬合之間達到平衡。優點:線性回歸的理解與解釋都十分直觀,並且還能通過正則化來降低過擬合的風險。
  • R語言從入門到精通:Day12--R語言統計--回歸分析
    回歸分析在現代統計學中非常重要,本次教程內容安排如下:  首先:看一看如何擬合和解釋回歸模型,然後回顧一系列鑑別模型潛在問題的方法,並學習如何解決它們;  其次:我們將探究變量選擇問題(對於所有可用的預測變量,如何確定哪些變量包含在最終的模型中?)
  • R 語言 lasso回歸
    接下來以線性回歸為例介紹其在R語言中的實現,當然在logistic回歸、cox回歸也是可用lasso的。以Employed為因變量,其餘變量為自變量(不包括年份)建立模型set.seed(123)x <- as.matrix(longley[,-c(6,7)])cv_lasso = cv.glmnet(x, longley$Employed,nfolds = 4,family = "gaussian", alpha = 1)
  • 零基礎的同學如何用stata做一元線性回歸模型?
    網上有關stata的教程有很多,但對於沒有基礎的同學來說,學起來稍微就有些吃力了。那麼,零基礎的同學應該如何學習呢?如何用stata做出滿意的一元線性回歸模型呢 ?小編邀請了不同學科的研究生分享stata的學習心得,希望能夠幫助更多對計量感興趣的同學們。分享者(小熊)
  • r語言 做wald檢驗_r語言wald檢驗怎麼做 - CSDN
    我們在做回歸擬合數據時,經常對因變量和自變量的假定是:自變量和因變量呈線性關係,logistic回歸是自變量和logitP,cox是指自變量和一個h(t)變換的一個東東(記不清了,抱歉),這些假定就叫線性假定。
  • 線性回歸和梯度下降的初學者教程
    假設有一個虛擬的數據集包含多對變量,即每位母親和她女兒的身高:通過這個數據集,我們如何預測另一位身高為63的母親的女兒的身高?方法是用線性回歸。首先找到最佳擬合線,然後用這條直線做預測。線性回歸是尋找數據集的最佳擬合線,這條線可以用來做預測。如何找到最佳擬合線?
  • 教程| 如何為單變量模型選擇最佳的回歸函數
    ,有助於快速調整參數和評估回歸模型的性能。請注意,我將分享我選擇模型的方法。模型的選擇有多種方式,可能會有其他不同的方法,但我描述的是最適合我的方式。 另外,這種方法只適用於單變量模型。單變量模型只有一個輸入變量。我會在之後的文章中描述如何用更多的輸入變量評估多變量模型。然而,在今天這篇文章中我們只關注基礎的單變量模型。
  • 一元回歸t檢驗與f檢驗_多元回歸模型的r檢驗f檢驗與t檢驗 - CSDN
    因此,作為自變量的因素與作為因變量的預測對象是否有關,相關程度如何,以及判斷這種相關程度的把握性多大,就成為進行回歸分析必須要解決的問題。進行相關分析,一般要求出相關關係,以相關係數的大小來判斷自變量和因變量的相關的程度。
  • 回歸模型擬合優度檢驗 - CSDN
    測試也執行相同的計算,然後計算Pearson擬合優度統計量    選擇組的數量就我所見,關於如何選擇組數g的指導很少。Hosmer和Lemeshow的模擬結論是基於使用的,建議如果我們在模型中有10個協變量 。直觀地說,使用較小的g值可以減少檢測錯誤規範的機會。
  • 逐步回歸分析調整後r2和模型的顯著性f值_多元線性回歸方程的顯著...
    在實際工作中,一般先進行相關分析,計算相關係數,然後建立回歸模型,最後用回歸模型進行推算或預測。相關分析與回歸分析的區別是:(1)相關分析研究的都是隨機變量,並且不分因變量和自變量;回歸分析研究的變量要定義出自變量和因變量,並且自變量是確定的普通變量,因變量是隨機變量。
  • r中回歸結果怎麼判定模型好壞_lasso回歸 模型好壞 - CSDN
    模型中不同形式的m(X)會幻化為不同的模型體系,一般可以將模型分為兩大類:m(X)可以幻化為數學公式,即公式模型,一般比較成熟的都是公式模型,例如回歸模型的理論與底蘊就比較完善,模型的假定都是可以進行檢驗的;
  • 教你用R畫列線圖(Nomogram),讓預測模型結果可視化!
    列線圖的基本原理,簡單的說,就是通過構建多因素回歸模型(常用的回歸模型,例如Cox回歸、Logistic回歸等),根據模型中各個影響因素對結局變量的貢獻程度(回歸係數的大小),給每個影響因素的每個取值水平進行賦分,然後再將各個評分相加得到總評分,最後通過總評分與結局事件發生概率之間的函數轉換關係,從而計算出該個體結局事件的預測值。