///|
pub struct RiskMeasure {
treated_risk : Double
control_risk : Double
risk_difference : Double
risk_ratio : Double
odds_ratio : Double
number_needed_to_treat : Double
}
///|
fn binary_group_rate(
outcomes : Array[Bool],
treatment : Array[Bool],
treated : Bool,
) -> Double {
let mut successes = 0
let mut total = 0
let n = if outcomes.length() < treatment.length() {
outcomes.length()
} else {
treatment.length()
}
for i in 0.. RiskMeasure {
let treated_risk = binary_group_rate(outcomes, treatment, true)
let control_risk = binary_group_rate(outcomes, treatment, false)
let difference = treated_risk - control_risk
let ratio = if control_risk == 0.0 {
1.0e300
} else {
treated_risk / control_risk
}
let treated_odds = if treated_risk == 1.0 {
1.0e300
} else {
treated_risk / (1.0 - treated_risk)
}
let control_odds = if control_risk == 1.0 {
1.0e300
} else {
control_risk / (1.0 - control_risk)
}
let odds_ratio = if control_odds == 0.0 {
1.0e300
} else {
treated_odds / control_odds
}
{
treated_risk,
control_risk,
risk_difference: difference,
risk_ratio: ratio,
odds_ratio,
number_needed_to_treat: if difference == 0.0 {
1.0e300
} else {
1.0 / difference.abs()
},
}
}
///|
pub fn binary_outcome_to_double(outcomes : Array[Bool]) -> Array[Double] {
let result = Array::new(capacity=outcomes.length())
for outcome in outcomes {
result.push(if outcome { 1.0 } else { 0.0 })
}
result
}
///|
pub fn threshold_outcome(
outcomes : Array[Double],
threshold : Double,
) -> Array[Bool] {
let result = Array::new(capacity=outcomes.length())
for outcome in outcomes {
result.push(outcome >= threshold)
}
result
}
///|
pub fn log_risk_ratio(measure : RiskMeasure) -> Double {
if measure.risk_ratio <= 0.0 {
0.0
} else {
@math.ln(measure.risk_ratio)
}
}
///|
pub fn relative_risk_reduction(measure : RiskMeasure) -> Double {
if measure.control_risk == 0.0 {
0.0
} else {
1.0 - measure.treated_risk / measure.control_risk
}
}