#r #tidyverse #dplyr #summarize
#r #tidyverse #dplyr #суммировать
Вопрос:
Я пытаюсь создать сводную таблицу точности, чувствительности и специфичности, используя AUC
функцию в psych
пакете. Я хотел бы определить входной вектор (t, вектор 4 x 1) для каждого уровня сгруппированной переменной.
То, что я пробовал, похоже, игнорирует группировку.
Пример:
library(tidyverse)
library(psych)
Data <- data.frame(Class = c("A","B","C","D"),
TP = c(198,185,221,192),
FP = c(1,1,6,1),
FN = c(42,55,19,48),
TN = c(569,570,564,569))
Data %>%
group_by(Class) %>%
mutate(Accuracy = AUC(t = unlist(.[1,2:5], use.names=FALSE))$Accuracy,
Sensitivity = AUC(t = unlist(.[1,2:5], use.names=FALSE))$Sensitivity,
Specificity = AUC(t = unlist(.[1,2:5], use.names=FALSE))$Specificity)
Это дает мне близкий к правильному результат, за исключением того, что значения точности, чувствительности и специфичности вычисляются только с первой строкой, а затем повторяются:
# A tibble: 4 x 8
# Groups: Class [4]
Class TP FP FN TN Accuracy Sensitivity Specificity
<fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 A 198 1 42 569 0.947 0.995 0.931
2 B 185 0 55 570 0.947 0.995 0.931
3 C 221 6 19 564 0.947 0.995 0.931
4 D 192 1 48 569 0.947 0.995 0.931
Я также пытался с summarize
:
Data %>%
group_by(Class) %>%
summarize(Accuracy = AUC(t = unlist(.[1,2:5], use.names=FALSE))$Accuracy,
Sensitivity = AUC(t = unlist(.[1,2:5], use.names=FALSE))$Sensitivity,
Specificity = AUC(t = unlist(.[1,2:5], use.names=FALSE))$Specificity)
Но результат такой же, как указано выше.
Желаемый результат — это уникальное вычисление для каждого уровня «Класса»
# A tibble: 4 x 8
Class TP FP FN TN Accuracy Sensitivity Specificity
<fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 A 198 1 42 569 0.95 0.99 0.93
2 B 185 0 55 570 0.93 0.99 0.91
3 C 221 6 19 564 0.97 0.97 0.97
4 D 192 1 48 569 0.94 0.99 0.92
Как мне вызвать функцию в summary или mutate для сохранения групп?
Ответ №1:
Это работает
Data %>%
group_by(Class) %>%
mutate(Accuracy = AUC(t = unlist(.[Class,2:5], use.names=FALSE))$Accuracy,
Sensitivity = AUC(t = unlist(.[Class,2:5], use.names=FALSE))$Sensitivity,
Specificity = AUC(t = unlist(.[Class,2:5], use.names=FALSE))$Specificity)
но, может быть, это более понятно
Data %>%
group_by(Class) %>%
mutate(Accuracy = AUC(t = c(TP, FP, FN, TN))$Accuracy,
Sensitivity = AUC(t = c(TP, FP, FN, TN))$Sensitivity,
Specificity = AUC(t = c(TP, FP, FN, TN))$Specificity)
Ответ №2:
Чтобы избежать вызова AUC
несколько раз для каждого класса, я бы написал оболочку, например, так:
# Load libraries
library(tidyverse)
library(psych)
# Create data frame
Data <- data.frame(Class = c("A","B","C","D"),
TP = c(198,185,221,192),
FP = c(1,1,6,1),
FN = c(42,55,19,48),
TN = c(569,570,564,569))
# Wrapper function
AUC_wrapper <- function(Class, TP, FP, FN, TN){
res <- AUC(t = c(TP, FP, FN, TN))
data.frame(Class = Class,
TP = TP,
FP = FP,
FN = FN,
TN = TN,
Accuracy = res$Accuracy,
Sensitivity = res$Sensitivity,
Specificity = res$Specificity)
}
# Run using purrr
pmap_dfr(Data, AUC_wrapper)
# Class TP FP FN TN Accuracy Sensitivity Specificity
# 1 A 198 1 42 569 0.9469136 0.9949749 0.9312602
# 2 B 185 1 55 570 0.9309494 0.9946237 0.9120000
# 3 C 221 6 19 564 0.9691358 0.9735683 0.9674099
# 4 D 192 1 48 569 0.9395062 0.9948187 0.9222042
Комментарии:
1. Это приводит к удалению
Class
имен и уровней выходных коэффициентов для меня