-
Notifications
You must be signed in to change notification settings - Fork 7
/
custom-functions.R
68 lines (54 loc) · 1.86 KB
/
custom-functions.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
call.mad <- function(vals){
b = 1.4826 # assuming a normal distribution
# from Huber 1981:
med.val <- median(vals) # median of the input data
abs.med.diff <- abs(vals-med.val) # absolute values minus med
abs.med <- median(abs.med.diff) # median of these values
MAD <- b*abs.med
MAD.normalized <- abs.med.diff/MAD # division by zero
MAD.normalized[is.na(MAD.normalized)] = 0 # doesn't protect against NAs that enter in data.in
return(MAD.normalized)
}
#'@title median absolute deviation outlier test
#'@name MAD
#'@aliases MAD
#'@aliases median.absolute.deviation
#'@param x values
#'@param windows vector of equal length to x specifying windows
#'@return a vector of MAD normalized values relative to an undefined rejection criteria (usually 2.5 or 3).
#'@keywords MAD
#'@author
#'Jordan S. Read
#'@export
MAD <- function(x, windows=parent.frame()$windows){
stopifnot(length(x) == length(windows))
# what is the underlying distribution? (important for assigning "b")
MAD.out <- vector(length=length(x))
un.win <- unique(windows)
for (i in 1:length(un.win)){
win.i <- un.win[i]
val.i <- windows == win.i
MAD.out[val.i] = call.mad(x[val.i])
}
return(MAD.out)
}
call.cv <- function(data.in){
CV <- 100*sd(data.in)/mean(data.in)
CV <- rep(CV,length(data.in))
return(CV)
}
coefficient.of.variation <- function(data.in){
if (is.data.frame(data.in)){
if (!"block.ID" %in% names(data.in)){stop("CV can only accept numeric data, or a data.frame with the block.ID column for windowed data")}
CV.out <- vector(length=nrow(data.in))
un.win <- unique(data.in$block.ID)
for (i in 1:length(un.win)){
win.i <- un.win[i]
val.i <- data.in$block.ID == win.i
CV.out[val.i] = call.cv(data.in$sensor.obs[val.i])
}
return(CV.out)
} else {
return(call.cv(data.in))
}
}