|
@@ -105,3 +105,93 @@ simple.compute_roc_metrics <- function(ROC) {
|
|
))
|
|
))
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#' Calculate covariance of AUC (deLonghi)
|
|
|
|
+#'
|
|
|
|
+#' @param roc roc as calculated by simple.roc
|
|
|
|
+#'
|
|
|
|
+#' @return standard deviation of AUC
|
|
|
|
+#'
|
|
|
|
+#' @export
|
|
|
|
+
|
|
|
|
+simple.sAUC <- function(roc) {
|
|
|
|
+ V1 = roc[roc$labels, 'V']
|
|
|
|
+ AUC = base::mean(V1)
|
|
|
|
+ V0 = roc[!roc$labels, 'V']
|
|
|
|
+ n0 = base::length(V0)
|
|
|
|
+ n1 = base::length(V1)
|
|
|
|
+
|
|
|
|
+ S0 = base::sum((V0 - AUC) * (V0 - AUC)) / (n0 - 1)
|
|
|
|
+ S1 = base::sum((V1 - AUC) * (V1 - AUC)) / (n1 - 1)
|
|
|
|
+ base::sqrt(S0 / n0 + S1 / n1)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#' Calculate covariance of AUC (approximation)
|
|
|
|
+#'
|
|
|
|
+#' @param roc roc as calculated by simple.roc
|
|
|
|
+#'
|
|
|
|
+#' @return standard deviation of AUC
|
|
|
|
+#'
|
|
|
|
+#' @export
|
|
|
|
+
|
|
|
|
+simple.sAUCapprox <- function(roc) {
|
|
|
|
+ n = base::length(roc$labels)
|
|
|
|
+ auc = simple.getAUC(roc)
|
|
|
|
+ auc_se = base::sqrt((auc * (1 - auc) + (n - 1) * (auc - 0.5)^2) / n)
|
|
|
|
+ auc_se
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#' Check whether two AUCs are statistically significantly different
|
|
|
|
+#'
|
|
|
|
+#' @param rocA roc of the first test as returned by simple.roc
|
|
|
|
+#' @param rocB roc of the second test as returned by simple.roc
|
|
|
|
+#'
|
|
|
|
+#' @return p of the test
|
|
|
|
+#'
|
|
|
|
+#' @export
|
|
|
|
+
|
|
|
|
+simple.sAUC2<-function(rocA,rocB){
|
|
|
|
+ #NCSS
|
|
|
|
+ #https://www.ncss.com/wp-content/themes/ncss/pdf/Procedures/NCSS/Comparing_Two_ROC_Curves-Paired_Design.pdf
|
|
|
|
+ #calculate combined variance of two predictions on the same dataset
|
|
|
|
+ #and give p-value that their performance is the same (or, with low p, that it is different)
|
|
|
|
+ V0A=rocA[!rocB$labels,'V']
|
|
|
|
+ V0B=rocB[!rocB$labels,'V']
|
|
|
|
+ V1A=rocA[rocA$labels,'V']
|
|
|
|
+ V1B=rocB[rocB$labels,'V']
|
|
|
|
+ AUCA=base::mean(V0A)
|
|
|
|
+ AUCB=base::mean(V0B)
|
|
|
|
+ n0=base::length(V0A)#the same as V0B
|
|
|
|
+ n1=base::length(V1A)#the same as V1B
|
|
|
|
+ base::print(base::sprintf('A=%f B=%f',AUCA,AUCB))
|
|
|
|
+ #variance of the 0 component, A
|
|
|
|
+ S0A=base::sum((V0A-AUCA)*(V0A-AUCA))/(n0-1)
|
|
|
|
+ #variance of 1 component, A
|
|
|
|
+ S1A=base::sum((V1A-AUCA)*(V1A-AUCA))/(n1-1)
|
|
|
|
+ #variance of A
|
|
|
|
+ SA=S0A/n0+S1A/n1
|
|
|
|
+ #variance of the 0 component, B
|
|
|
|
+ S0B=base::sum((V0B-AUCB)*(V0B-AUCB))/(n0-1)
|
|
|
|
+ #variance of 1 component, B
|
|
|
|
+ S1B=base::sum((V1B-AUCB)*(V1B-AUCB))/(n1-1)
|
|
|
|
+ #variance of B
|
|
|
|
+ SB=S0B/n0+S1B/n1
|
|
|
|
+ #covariance 0 component
|
|
|
|
+ S0AB=base::sum((V0A-AUCA)*(V0B-AUCB))/(n0-1)
|
|
|
|
+ #covariance 1 component
|
|
|
|
+ S1AB=base::sum((V1A-AUCA)*(V1B-AUCB))/(n1-1)
|
|
|
|
+ #covariance
|
|
|
|
+ SAB=S0AB/n0+S1AB/n1
|
|
|
|
+ S=SA+SB-2*SAB
|
|
|
|
+ #is there a significant difference
|
|
|
|
+ z=base::abs(AUCA-AUCB)/base::sqrt(S)
|
|
|
|
+ p=2*stats::pnorm(z,mean=0,sd=1,lower.tail=FALSE)
|
|
|
|
+
|
|
|
|
+ #is A larger than B
|
|
|
|
+ #z=(AUCA-AUCB)/sqrt(S)
|
|
|
|
+ #p=pnorm(z,mean=0,sd=1,lower.tail=FALSE)
|
|
|
|
+
|
|
|
|
+ base::print(base::sprintf('SA2=%f SB2=%f SAB2=%f S2=%f S=%f z=%f p=%f',SA,SB,SAB,S,base::sqrt(S),z,p))
|
|
|
|
+ p
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|