Сравнение нескольких AUC параллельно (R) - PullRequest
1 голос
/ 13 марта 2020

Я использую пакет pRO C в r, чтобы вычислить и сравнить AUC нескольких тестов, чтобы увидеть, какой тест обладает лучшей способностью различать пациентов и контролей. Тем не менее, у меня есть большое количество тестов, и я хочу провести серию парных сравнений каждого теста AU C с каждым другим тестом, а затем исправить для нескольких сравнений. Насколько я понял, мой код (пример с имитированным и воспроизводимым набором данных ниже):

#load pROC
library(pROC)

#generate df with random numbers
set.seed(123)
df <- data.frame(disease_status = rbinom(n=100, size=1, prob=0.20),
                 test1 = rnorm(100, mean=15, sd=4),
                 test2 = rnorm(100, mean=30, sd=2),
                 test3 = rnorm(100, mean=50, sd=3))

#create roc object for test1, test2, test3
roc.out_test1<-roc(df$disease_status, df$test1, plot=TRUE, smooth = FALSE)
roc.out_test2<-roc(df$disease_status, df$test2, plot=TRUE, smooth = FALSE)
roc.out_test3<-roc(df$disease_status, df$test3, plot=TRUE, smooth = FALSE)

#compare the AUC of test1 and test 2
roc.test(roc.out_test1, roc.out_test2, reuse.auc=TRUE, method="delong", na.rm=TRUE)

#DeLong's test for two correlated ROC curves
#data:  roc.out_test1 and roc.out_test2
#Z = 0.60071, p-value = 0.548
#alternative hypothesis: true difference in AUC is not equal to 0
#sample estimates:
#AUC of roc1 AUC of roc2 
#0.5840108   0.5216802 

#create a function to do above for all comparisons
vec_ROCs1 <- c("roc.out_test1,", "roc.out_test2,", "roc.out_test3,")
vec_ROCs2 <- c("roc.out_test1", "roc.out_test2", "roc.out_test3")
ROCs2_specifications  <- paste0(vec_ROCs2, ",", "reuse.auc=TRUE")
test <- unlist(lapply(ROCs2_specifications, function(x) paste0(vec_ROCs1, x)))
test2 <- lapply(test, function(x) roc.test(x))

#Error in roc.test.default(x) : 
#  argument "predictor1" is missing, with no default 

Пожалуйста, дайте мне знать ваши мысли и предложения о том, как это исправить!

Спасибо.

Ответы [ 2 ]

1 голос
/ 14 марта 2020

Функция ro c .test () ожидает ввод объекта ro c. Список test - это просто строки символов всех аргументов, с которыми функция не знает, что делать. Список также включает в себя сравнения тестов с самими собой, то есть "ro c .out_test1, ro c .out_test1, reuse.auc = TRUE" Я предполагаю, что вам на самом деле не нужно это делать, и что есть только 3 сравнения что вам нужно 1 на 2, 1 на 3, 2 на 3. Пакет purrr предоставляет функции map, аналогичные lapply, а map2 позволяет выполнять итерацию 2 списков одновременно. Вам нужно создать 2 списка действительно ro c объектов и перебрать их.

#load pROC
library(pROC)
library(dplyr)
library(purrr) #For map2 function

#generate df with random numbers
set.seed(123)
df <- data.frame(disease_status = rbinom(n=100, size=1, prob=0.20),
                 test1 = rnorm(100, mean=15, sd=4),
                 test2 = rnorm(100, mean=30, sd=2),
                 test3 = rnorm(100, mean=50, sd=3))

#create roc object for test1, test2, test3
roc.out_test1<-roc(df$disease_status, df$test1, plot=TRUE, smooth = FALSE)
roc.out_test2<-roc(df$disease_status, df$test2, plot=TRUE, smooth = FALSE)
roc.out_test3<-roc(df$disease_status, df$test3, plot=TRUE, smooth = FALSE)

#compare the AUC of test1 and test 2
roc.test(roc.out_test1, roc.out_test2, reuse.auc=TRUE, method="delong", na.rm=TRUE)

roc_new <- function(test1,  test2){
  roc.test(test1, test2, reuse.auc=TRUE, method="delong", na.rm=TRUE)
}

#List of all tests
all_tests <- list(roc.out_test1,
                  roc.out_test2,
                  roc.out_test3) 

#Create unique combos of tests
unique_combos <- expand.grid(1:3, 1:3) %>% 
  filter(Var1 < Var2) %>% #exludes duplicate comparisons, 
                      #each col provides the index for the 2 lists to iterate over
  mutate(names = paste(Var1, " V ",  Var2)) #Create col to name final output list


#Create 2 lists to iterate over
#Create list 1
(test1 <- all_tests[as.numeric(unique_combos$Var1)])
#Create list 2
(test2 <- all_tests[as.numeric(unique_combos$Var2)])

#Iterate over both lists
output <- map2(test1, test2, roc_new)
names(output) <- unique_combos$names

1 голос
/ 14 марта 2020

Следующее должно работать, пожалуйста, проверьте это. Я не написал все детали, но вы можете задать мне другие вопросы, если вы не понимаете код.

#load pROC
library(pROC)
#> Type 'citation("pROC")' for a citation.
#> 
#> Attaching package: 'pROC'
#> The following objects are masked from 'package:stats':
#> 
#>     cov, smooth, var

#generate df with random numbers
set.seed(123)
df <- data.frame(disease_status = rbinom(n=100, size=1, prob=0.20),
                 test1 = rnorm(100, mean=15, sd=4),
                 test2 = rnorm(100, mean=30, sd=2),
                 test3 = rnorm(100, mean=50, sd=3))

#create roc object for test1, test2, test3
roc.out_test1<-roc(df$disease_status, df$test1, plot=TRUE, smooth = FALSE)
#> Setting levels: control = 0, case = 1
#> Setting direction: controls < cases

roc.out_test2<-roc(df$disease_status, df$test2, plot=TRUE, smooth = FALSE)
#> Setting levels: control = 0, case = 1
#> Setting direction: controls < cases

roc.out_test3<-roc(df$disease_status, df$test3, plot=TRUE, smooth = FALSE)
#> Setting levels: control = 0, case = 1
#> Setting direction: controls < cases

# compare the AUC of test1 and test 2
roc.test(roc.out_test1, roc.out_test2, reuse.auc = TRUE, method = "delong", na.rm = TRUE)
#> 
#>  DeLong's test for two correlated ROC curves
#> 
#> data:  roc.out_test1 and roc.out_test2
#> Z = 0.60071, p-value = 0.548
#> alternative hypothesis: true difference in AUC is not equal to 0
#> sample estimates:
#> AUC of roc1 AUC of roc2 
#>   0.5840108   0.5216802

Теперь мы сгенерируем список всех возможных комбинаций трех тестов и запустим функцию roc.test, используя те же параметры, что и вы.

all_tests <- combn(
  list(
    "test1" = roc.out_test1,
    "test2" = roc.out_test2,
    "test3" = roc.out_test3
  ),
  FUN = function(x, ...) roc.test(x[[1]], x[[2]]),
  m = 2,
  simplify = FALSE, 
  reuse.auc = TRUE, 
  method = "delong", 
  na.rm = TRUE
)

Вывод список choose(3, 2) = 3 элементов (т. е. количество комбинаций из n элементов, взятых по 2 за раз), и каждый элемент списка является тестом. Например, это то же самое, что и ваш предыдущий тест:

all_tests[[1]]
#> 
#>  DeLong's test for two correlated ROC curves
#> 
#> data:  x[[1]] and x[[2]]
#> Z = 0.60071, p-value = 0.548
#> alternative hypothesis: true difference in AUC is not equal to 0
#> sample estimates:
#> AUC of roc1 AUC of roc2 
#>   0.5840108   0.5216802

Единственная проблема здесь в том, что трудно определить, какие тесты используются в сравнениях, поэтому мы также можем добавить список имен:

tests_names <- combn(
  list("test1", "test2", "test3"), 
  m = 2, 
  FUN = paste, 
  simplify = TRUE, 
  collapse = "_"
)
all_tests <- setNames(all_tests, tests_names)

Это результат.

names(all_tests)
#> [1] "test1_test2" "test1_test3" "test2_test3"

Имена объектов помечают тесты, которые используются в сравнении.

all_tests$test1_test2
#> 
#>  DeLong's test for two correlated ROC curves
#> 
#> data:  x[[1]] and x[[2]]
#> Z = 0.60071, p-value = 0.548
#> alternative hypothesis: true difference in AUC is not equal to 0
#> sample estimates:
#> AUC of roc1 AUC of roc2 
#>   0.5840108   0.5216802

Создано в 2020-03-14 пакетом Представлять (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...