Создайте ROC-кривую с помощью for или sapply

После долгих поисков я не смог найти ответ на свою проблему. Я хотел бы сгенерировать ROC-кривую с помощью pROC pakkage, используя цикл for или sapply.

Моя база данных выглядит так (только с 26 столбцами и 74 строками):

PT Bpt PA mnT1G mnT01
1   1  1   2.3   4.5
1   2  0   1.2   3.2 
2   1  1   5.4   2.1

Я могу сделать кривую ROC "вручную":

plot.new()
roc1 <- roc(cor.datT$PA, cor.datT$mT1G, percent=TRUE, partial.auc=c(100, 90), partial.auc.correct=TRUE, 
            partial.auc.focus="sens", ci=TRUE, boot.n=100, ci.alpha=0.9, stratified=FALSE, plot=TRUE, col= 'red')
roc2 <- roc(cor.datT$PA, cor.datT$mT01, plot=TRUE, add=TRUE, percent=roc1$percent, col = 'blue')

Для "автоматического" я ​​попытался:

Первая кривая roc всегда mnT1G:

rocT1G <- roc(cor.datT$PA, cor.datT$mnT1G, percent=TRUE, partial.auc=c(100, 90), partial.auc.correct=TRUE, partial.auc.focus="sens", ci=TRUE, boot.n=100, ci.alpha=0.9, stratified=FALSE, plot=TRUE, col= 'red')

Добавьте другие кривые roc (data$Img - все имена изображений (например, T1G, T01 и т. Д.) Из другого кадра данных). Я так понимаю все они будут голубыми

sapply(unique(data$Img[data$Img != "T1G"]), FUN = function(i) paste("roc",i,sep="") <- roc(cor.datT$PA, cor.datT[paste("mn",i, sep = "")], plot=TRUE, add=TRUE, percent=rocT1G$percent, col = 'blue'), simplify = FALSE)

Но я получаю эту ошибку:

Ошибка в roc.default(cor.datT$PA, cor.datT[paste("mn", i, sep = "")],: предиктор должен быть числовым или упорядоченным.

То же самое происходит с для цикла:

for (i in unique(data$Img[data$Img != "T1G"])){
    plot.new()
    rocT1G <- roc(cor.datT$PA, cor.datT$mnT1G, percent=TRUE, partial.auc=c(100, 90), partial.auc.correct=TRUE, partial.auc.focus="sens", ci=TRUE, boot.n=100, ci.alpha=0.9, stratified=FALSE, plot=TRUE, col= 'red')
    paste("roc",i,sep="") <- roc(cor.datT$PA, cor.datT[paste("mn",i, sep = "")], plot=TRUE, add=TRUE, percent=rocT1G$percent, col = 'blue')
}

Я проверил столбцы, и они все числовые. Так может быть что-то не так с классом в моем сценарии?

2 ответа

Решение

Как вы отметили в комментарии к моему другому ответу, проблема в том, что вы получаете конкретно data.frameиз вашей добычи.

В data.frame, извлечение с одним символом возвращает data.frame, Это задокументировано в ? Extract.data.frame:

Кадры данных могут быть проиндексированы в нескольких режимах. Когда [и [[используются с одним векторным индексом (x[i] или x[[i]])), они индексируют фрейм данных, как если бы это был список.

И, глядя на ? Извлечение:

Рекурсивные (подобные списку) объекты

Индексирование по [аналогично атомарным векторам и выбирает список заданных элементов.

Это не так очевидно из текста, но для извлечения столбца в вектор необходимо использовать две скобки [[, так

class(cor.datT[[paste("mn",i, sep = "")]])

должен быть вектор.

Теперь должен работать следующий код:

rocT1G <- roc(cor.datT$PA, cor.datT$mnT1G, percent=TRUE, partial.auc=c(100, 90), partial.auc.correct=TRUE, partial.auc.focus="sens", ci=TRUE, boot.n=100, ci.alpha=0.9, stratified=FALSE, plot=TRUE, col= 'red')
for (i in unique(data$Img[data$Img != "T1G"])){
    roc(cor.datT$PA, cor.datT[[paste("mn",i, sep = "")]], plot=TRUE, add=TRUE, percent=rocT1G$percent, col = 'blue')
}

Один из ваших столбцов не является числовым, как вы ожидаете. К сожалению, сообщение об ошибке от R не говорит вам, на какой итерации цикла возникает проблема, но вы можете легко добавить print заявление в ваш цикл, чтобы выяснить, какой столбец приводит к проблеме

for (i in unique(data$Img[data$Img != "T1G"])){
    print(i)
    plot.new()
    rocT1G <- roc(cor.datT$PA, cor.datT$mnT1G, percent=TRUE, partial.auc=c(100, 90), partial.auc.correct=TRUE, partial.auc.focus="sens", ci=TRUE, boot.n=100, ci.alpha=0.9, stratified=FALSE, plot=TRUE, col= 'red')
    paste("roc",i,sep="") <- roc(cor.datT$PA, cor.datT[paste("mn",i, sep = "")], plot=TRUE, add=TRUE, percent=rocT1G$percent, col = 'blue')
}

Будет напечатан последний номер столбца. Вы можете увидеть, что происходит с колонкой:

class(cor.datT[paste("mn",i, sep = "")])
str(cor.datT[paste("mn",i, sep = "")])

В целом, вы можете довольно быстро проверить все столбцы вашего фрейма данных с помощью

str(cor.datT)

Проверьте для столбцов класса character или же factor особенно.

Другие вопросы по тегам