File size: 5,528 Bytes
6ca4b94 |
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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# read arguments from endpoint calling subroutine
args = commandArgs(trailingOnly = TRUE)
N = as.numeric(args[1])
ToSelect = as.numeric(args[2])
BaseRate = as.numeric(args[3]) / 100
Validity = as.numeric(args[4])
# DISCLAIMER: The code below is not my original work. It was obtained from a third-party source and used for learning purposes. Credit goes to the original author.
# Adapted from: https://www.r-bloggers.com/2012/02/reflect-your-personnel-selection-r-taylor-russell-tables/
F1 = function(P) {
SPLIT = 0.42
A0 = 2.50662823884
A1 = -18.61500062529
A2 = 41.391199773534
A3 = -25.44106049637
B1 = -8.4735109309
B2 = 23.08336743743
B3 = -21.06224101826
B4 = 3.13082909833
C0 = -2.78718931138
C1 = -2.29796479134
C2 = 4.85014127135
C3 = 2.32121276858
D1 = 3.54388924762
D2 = 1.63706781897
Q = P - 0.5
if (abs(Q) <= SPLIT) {
R = Q*Q
PPN = Q * (((A3 * R + A2) * R + A1) * R + A0) / ((((B4 * R + B3) * R + B2) * R + B1)*R +1.0)
return(PPN)
}
R = P
if (Q > 0) {R =1.0-P}
if (R <= 0) {
print("You have entered a value that is not permitted. The result is false.")
return(0)
}
R = sqrt(-log(R))
PPN = (((C3 * R + C2) * R + C1) * R + C0) / ((D2 * R + D1) * R + 1.0)
if (Q < 0) {PPN =-PPN}
return(PPN)
}
F2 = function(X) {
P1A = 242.667955230532
P1B = 21.97926616182942
P1C = 6.996383488661914
P1D = -3.5609843701815E-02
Q1A = 215.058875869861
Q1B = 91.1649054045149
Q1C = 15.0827976304078
Q1D = 1.0
P2A = 300.459261020162
P2B = 451.918953711873
P2C = 339.320816734344
P2D = 152.98928504694
P2E = 43.1622272220567
P2F = 7.21175825088309
P2G = .564195517478994
P2H = -1.36864857382717E-07
Q2A = 300.459260956983
Q2B = 790.950925327898
Q2C = 931.35409485061
Q2D = 638.980264465631
Q2E = 277.585444743988
Q2F = 77.0001529352295
Q2G = 12.7827273196294
Q2H = 1.0
P3A = -2.99610707703542E-03
P3B = -4.94730910623251E-02
P3C = -.226956593539687
P3D = -.278661308609648
P3E = -2.23192459734185E-02
Q3A = 1.06209230528468E-02
Q3B = .19130892610783
Q3C = 1.05167510706793
Q3D = 1.98733201817135
Q3E = 1.0
SQRT2 = 1.4142135623731
SQRTPI = 1.77245385090552
Y = X/SQRT2
if (Y < 0) {
Y = -Y
SN = -1.0
} else {
SN = 1.0
}
Y2 = Y * Y
if (Y < 0.46875) {
R1 = ((P1D * Y2 + P1C) * Y2 + P1B) * Y2 + P1A
R2 = ((Q1D * Y2 + Q1C) * Y2 + Q1B) * Y2 + Q1A
ERFVAL = Y * R1 / R2
if (SN == 1) LOAREA = 0.5 + 0.5 * ERFVAL
else LOAREA = 0.5 - 0.5 * ERFVAL
} else {
if (Y < 4.0) {
R1 = ((((((P2H * Y + P2G) * Y + P2F) * Y + P2E) * Y + P2D) * Y + P2C) * Y + P2B) * Y + P2A
R2 = ((((((Q2H * Y + Q2G) * Y + Q2F) * Y + Q2E) * Y + Q2D) * Y + Q2C) * Y + Q2B) * Y + Q2A
ERFCVAL = exp(-Y2) * R1 / R2
} else {
Z = Y2 * Y2
R1 = (((P3E * Z + P3D) * Z + P3C) * Z + P3B) * Z + P3A
R2 = (((Q3E * Z + Q3D) * Z + Q3C) * Z + Q3B) * Z + Q3A
ERFCVAL = (exp(-Y2) / Y) * (1.0 / SQRTPI + R1 / (R2 * Y2))
}
if (SN == 1) LOAREA = 1.0 - 0.5 * ERFCVAL
else LOAREA = 0.5 * ERFCVAL
}
UPAREA = 1.0 - LOAREA
return(UPAREA)
}
F3 = function(H1, HK, R) {
X = c(0.04691008, 0.23076534, 0.5, 0.76923466, 0.95308992)
W = c(0.018854042, 0.038088059, 0.0452707394, 0.038088059, 0.018854042)
H2 = HK
H12 = (H1*H1 + H2*H2)/2.0
BV = 0
if (abs(R) >= 0.7) {
R2 = 1.0-R*R
R3 = sqrt(R2)
if (R < 0) H2 = -H2
H3 = H1*H2
H7 = exp(-H3 / 2.0)
if (R2 != 0) {
H6 = abs(H1 - H2)
H5 = H6 * H6 / 2.0
H6 = H6 / R3
AA = 0.5 - (H3 / 8.0)
AB = 3.0 - (2.0 * AA * H5)
BV = 0.13298076 * H6 * AB * F2(H6) - exp(-H5 / R2) * (AB + AA * R2) * 0.053051647
for (i in 1:5) {
R1 = R3 * X[i]
RR = R1 * R1
R2 = sqrt( 1.0- RR)
BV = BV - W[i] * exp(-H5 / RR) * (exp(-H3 / (1.0 + R2)) / R2 / H7 - 1.0 - AA * RR)
}
}
if (R > 0 & H1 > H2) {
BV = BV * R3 * H7 + F2(H1)
return(BV)
}
if (R > 0 & H1 <= H2) {
BV = BV * R3 * H7 + F2(H2)
return(BV)
}
if (R < 0 & (F2(H1) - F2(H2)) < 0) {
BV = 0 - BV * R3 * H7
return(BV)
}
if (R < 0 & (F2(H1) - F2(H2)) >= 0) {
BV = (F2(H1) - F2(H2)) - BV * R3 * H7
return(BV)
}
}
H3 = H1 * H2
for (i in 1:5)
{
R1 = R * X[i]
RR2 = 1.0 - R1 * R1
BV = BV + W[i] * exp((R1 * H3 - H12) / RR2) / sqrt(RR2)
}
BV = F2(H1) * F2(H2) + R * BV
return(BV)
}
true_positives = function(N, ToSelect,BaseRate, Validity) {round(F3(F1(1.0-ToSelect/N), F1(1.0-BaseRate), Validity)/(ToSelect/N)*ToSelect,1)}
false_positives = function(N, ToSelect,BaseRate, Validity) {round(ToSelect-F3(F1(1.0-ToSelect/N), F1(1.0-BaseRate), Validity)/(ToSelect/N)*ToSelect,1)}
false_negatives = function(N, ToSelect,BaseRate, Validity) {round(N*BaseRate - F3(F1(1.0-ToSelect/N), F1(1.0-BaseRate), Validity)/(ToSelect/N)*ToSelect,1)}
true_negatives = function(N, ToSelect,BaseRate, Validity) {N - true_positives(N, ToSelect,BaseRate, Validity) - false_positives(N, ToSelect,BaseRate, Validity) - false_negatives(N, ToSelect,BaseRate, Validity)}
payload = list(
"true_positives" = true_positives(N, ToSelect,BaseRate, Validity),
"false_positives" = false_positives(N, ToSelect,BaseRate, Validity),
"false_negatives" = false_negatives(N, ToSelect,BaseRate, Validity),
"true_negatives" = true_negatives(N, ToSelect,BaseRate, Validity)
)
# export results as JSON for the endpoint
library(jsonlite)
cat(toJSON(payload, auto_unbox = TRUE)) |