Diff of /ATAC/Functions/MAD.R [000000] .. [40a513]

Switch to side-by-side view

--- a
+++ b/ATAC/Functions/MAD.R
@@ -0,0 +1,33 @@
+#### Unsymmetric Distributions and the Double MAD
+#ref: https://eurekastatistics.com/using-the-median-absolute-deviation-to-find-outliers/
+
+DoubleMAD <- function(x, zero.mad.action="warn"){
+   # The zero.mad.action determines the action in the event of an MAD of zero.
+   # Possible values: "stop", "warn", "na" and "warn and na".
+   x         <- x[!is.na(x)]
+   m         <- median(x)
+   abs.dev   <- abs(x - m)
+   left.mad  <- median(abs.dev[x<=m])
+   right.mad <- median(abs.dev[x>=m])
+   if (left.mad == 0 || right.mad == 0){
+      if (zero.mad.action == "stop") stop("MAD is 0")
+      if (zero.mad.action %in% c("warn", "warn and na")) warning("MAD is 0")
+      if (zero.mad.action %in% c(  "na", "warn and na")){
+         if (left.mad  == 0) left.mad  <- NA
+         if (right.mad == 0) right.mad <- NA
+      }
+   }
+   return(c(left.mad, right.mad))
+}
+
+DoubleMADsFromMedian <- function(x, zero.mad.action="warn"){
+   # The zero.mad.action determines the action in the event of an MAD of zero.
+   # Possible values: "stop", "warn", "na" and "warn and na".
+   two.sided.mad <- DoubleMAD(x, zero.mad.action)
+   m <- median(x, na.rm=TRUE)
+   x.mad <- rep(two.sided.mad[1], length(x))
+   x.mad[x > m] <- two.sided.mad[2]
+   mad.distance <- abs(x - m) / x.mad
+   mad.distance[x==m] <- 0
+   return(mad.distance)
+}
\ No newline at end of file