///|
pub struct DifferenceInDifferencesResult {
treated_pre_mean : Double
treated_post_mean : Double
control_pre_mean : Double
control_post_mean : Double
treatment_change : Double
control_change : Double
estimate : Double
standard_error : Double
}
///|
fn select_panel(
values : Array[Double],
group : Array[Bool],
period : Array[Bool],
selected_group : Bool,
selected_period : Bool,
) -> Array[Double] {
let result = Array::new()
for i in 0.. DifferenceInDifferencesResult {
let treated_pre = select_panel(
outcomes, treated_group, post_period, true, false,
)
let treated_post = select_panel(
outcomes, treated_group, post_period, true, true,
)
let control_pre = select_panel(
outcomes, treated_group, post_period, false, false,
)
let control_post = select_panel(
outcomes, treated_group, post_period, false, true,
)
let treatment_change = mean(treated_post) - mean(treated_pre)
let control_change = mean(control_post) - mean(control_pre)
let estimate = treatment_change - control_change
let treated_variance = if treated_pre.length() == 0 ||
treated_post.length() == 0 {
0.0
} else {
variance(treated_pre) / treated_pre.length().to_double() +
variance(treated_post) / treated_post.length().to_double()
}
let control_variance = if control_pre.length() == 0 ||
control_post.length() == 0 {
0.0
} else {
variance(control_pre) / control_pre.length().to_double() +
variance(control_post) / control_post.length().to_double()
}
{
treated_pre_mean: mean(treated_pre),
treated_post_mean: mean(treated_post),
control_pre_mean: mean(control_pre),
control_post_mean: mean(control_post),
treatment_change,
control_change,
estimate,
standard_error: (treated_variance + control_variance).sqrt(),
}
}
///|
pub struct EventStudyPoint {
relative_time : Int
treated_mean : Double
control_mean : Double
effect : Double
count : Int
}
///|
pub fn event_study(
outcomes : Array[Double],
treated_group : Array[Bool],
relative_time : Array[Int],
) -> Array[EventStudyPoint] {
let times = Array::new()
for time in relative_time {
if !times.contains(time) {
times.push(time)
}
}
let result : Array[EventStudyPoint] = Array::new(capacity=times.length())
for time in times {
let treated = Array::new()
let control = Array::new()
for i in 0.. Double {
let pre_treated = Array::new()
let pre_control = Array::new()
for i in 0.. Array[Double] {
let weights = Array::make(donor_profiles.length(), 1.0)
for i in 0.. 0.0 {
for i in 0.. Double {
weighted_mean(outcomes, weights)
}