Создайте несколько матриц путаницы в R, используя циклы

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

Итак, для кадра данных ниже мне нужна матрица путаницы, когда Value = 1, Value = 2, Value =3

  observed predicted Value
       1      1      1
       0      1      1
       1      0      2
       0      0      2
       1      1      3
       0      0      3

и увидеть результаты, такие как:

Value  Sensitivity  Specificity  PPV  NPV
1        .96            .71      .84  .95
2        .89            .63      .30  .45     
3        .88            .95      .28  .80

Это то, что я пробовал с воспроизводимым примером. Я пытаюсь написать цикл, который просматривает каждую строку, определяет, есть ли Age = 1, а затем извлекает значения из прогнозируемых и наблюдаемых столбцов для создания матрицы путаницы. Затем я вручную вытаскиваю значения из матрицы путаницы, чтобы записать sen, spec, ppv и npv, и пытаюсь объединить все матрицы вместе. А затем цикл снова начинается с Age = 2.

data(scat)
df<-scat %>% transmute(observed=ifelse(Site= = "YOLA","case", "control"), predicted=ifelse(Location= = "edge","case", "control"),Age)

x<-1 #evaluate at ages 1 through 5
for (i in dim(df)[1]) { #for every row in df
  while(x<6) { #loop stops at Age=5
    if (x=df$Age) {
      q<-confusionMatrix(data = df$predicted, reference = df$observed, positive = "case")
      sensitivity = q$table[1,1]/(q$table[1,1]+q$table[2,1])
      specificity = q$table[2,2]/(q$table[2,2]+q$table[1,2])
      ppv = q$table[1,1]/(q$table[1,1]+q$table[1,2])
      npv = q$table[2,2]/(q$table[2,2]+q$table[2,1])
      matrix(c(sensitivity, specificity, ppv, npv),ncol=4,byrow=TRUE)
    }
  }
  x <- x + 1 #confusion matrix at next Age value
}

final<- rbind(matrix) #combine all the matrices together

Однако эта петля совершенно нефункциональна. Я не уверен, где ошибка.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
460
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш код можно упростить, и желаемый результат достигается следующим образом:

library(caret)
library(dplyr)

data(scat)

df <- scat %>% 
  transmute(observed = factor(ifelse(Site == "YOLA","case", "control")), 
            predicted = factor(ifelse(Location == "edge","case", "control")),
            Age)

final <- t(sapply(sort(unique(df$Age)), function(i) { 
  
  q <- confusionMatrix(data      = df$predicted[df$Age == i],
                       reference = df$observed[df$Age == i], 
                       positive  = "case")$table
  
  c(sensitivity = q[1, 1] / (q[1, 1] + q[2, 1]),
    specificity = q[2, 2] / (q[2, 2] + q[1, 2]),
    ppv         = q[1, 1] / (q[1, 1] + q[1, 2]),
    npv         = q[2, 2] / (q[2, 2] + q[2, 1]))
}))

В результате чего

final
#>      sensitivity specificity        ppv       npv
#> [1,]         0.0   0.5625000 0.00000000 0.8181818
#> [2,]         0.0   1.0000000        NaN 0.8000000
#> [3,]         0.2   0.5882353 0.06666667 0.8333333
#> [4,]         0.0   0.6923077 0.00000000 0.6923077
#> [5,]         0.5   0.6400000 0.25000000 0.8421053

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

  1. Вам нужны факторные столбцы, а не символьные столбцы для confusionMatrix
  2. Вы увеличивали по строкам df, но вам нужна одна итерация для каждого уникального возраста, а не для каждой строки в вашем фрейме данных.
  3. Ваша строка для увеличения x происходит вне цикла while, поэтому x никогда не увеличивается, и цикл никогда не завершается, поэтому консоль просто зависает.
  4. Вы выполняете if (x = df$Age), но вам нужно == для проверки равенства.
  5. В любом случае сравнивать x с df$Age не имеет смысла, потому что x имеет длину 1, а df$Age — длинный вектор.
  6. Вы делаете ненужное повторение, делая q$table каждый раз. Вы можете просто сделать q равным q$table, чтобы сделать ваш код более читабельным и менее подверженным ошибкам.
  7. Вы вызываете matrix в конце цикла, но нигде его не сохраняете, поэтому весь цикл на самом деле ничего не делает.
  8. Вы пытаетесь rbind объект с именем matrix в последней строке, который не существует
  9. Отсутствие пробелов между математическими операторами, запятыми и переменными делает код менее читабельным и трудным для отладки. Я не просто говорю это как стилистический момент; это основной источник ошибок, которые я часто вижу здесь, на SO.

Большое спасибо за развернутый ответ и объяснение! Я не был знаком с sapply, поэтому я немного почитал об этом. И я добавляю этот комментарий для всех в будущем, я также хотел иметь столбец с пометкой Age и перечислением возрастов в виде строк, поэтому я преобразовал final в фрейм данных, а затем сделал setDT(final, keep.rownames = "Age").

PleaseHelp 15.12.2020 17:26

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