roc.R 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #' Create a ROC curve
  2. #'
  3. #' @param labels vector of outcomes
  4. #' @param scores vector of variable values
  5. #' @param decreasing ordering of scores
  6. #'
  7. #' @return data frame with columns TPR, FPR, labels, scores, V
  8. #' V is combination of V0 (negative cases) and V1 (positive cases)
  9. #' V0 is portion of positive cases with value larger than score
  10. #' V1 is portion of negative cases with value below score
  11. #'
  12. #' @export
  13. simple.roc <- function(labels, scores, decreasing = TRUE) {
  14. # Odstranimo NA vrednosti iz labels in scores
  15. valid_data = stats::complete.cases(labels, scores)
  16. labels = labels[valid_data]
  17. scores = scores[valid_data]
  18. labels <- labels[order(scores, decreasing=decreasing)]
  19. scores <- scores[order(scores, decreasing=decreasing)]
  20. labels = base::as.logical(labels)
  21. x = base::data.frame(TPR = base::cumsum(labels) / base::sum(labels),
  22. FPR = base::cumsum(!labels) / base::sum(!labels),
  23. labels, scores)
  24. s1 = scores[labels]
  25. s0 = scores[!labels]
  26. #V0 are 0 components of test, for each test-negative case find number of positive cases with value above it (ideally, count is equal to n1, number of positive cases)
  27. V0 = base::sapply(s0, psi01, s=s1)
  28. #V1 are 1 components of test; for each test-positive case find number of negative cases with score below its score (ideally, count is equal to n0, number of negative cases)
  29. V1 = base::sapply(s1, psi10, s=s0)
  30. n0=base::length(s0)
  31. n1=base::length(s1)
  32. #convert V0 to portions, to [0,1] range
  33. V0=V0/n1
  34. #convert V1 to portions, to [0,1] range
  35. V1=V1/n0
  36. V = labels
  37. V[labels] <- V1
  38. V[!labels] <- V0
  39. x$V = V
  40. x
  41. }
  42. psi01 <- function(y, s) {
  43. v1 = base::sum(s > y, na.rm = TRUE)
  44. v2 = base::sum(s == y, na.rm = TRUE)
  45. v1 + 0.5 * v2
  46. }
  47. psi10 <- function(x, s) {
  48. v1 = base::sum(s < x, na.rm = TRUE)
  49. v2 = base::sum(s == x, na.rm = TRUE)
  50. v1 + 0.5 * v2
  51. }