Breaking Down the R Code Line by Line
I. Step 1: Adding Distance and Ranking Columns
control_df[, `:=`(dist = distances, rank_dist = frank(distances, [Link] =
"first"))]
distances is assumed to be a numeric vector of distance values.
dist column is created in control_df to store these distance values.
rank_dist is assigned ranks using frank() (fast rank function in [Link]).
o [Link] = "first" ensures that if multiple rows have the same distance,
they are ranked in the order they appear in the dataset.
II. Step 2: Checking best_match_restriction
if (!best_match_restriction){
df_output = as_tibble(control_df[rank_dist <= n_match])
}
If best_match_restriction is FALSE, then all controls with rank_dist <= n_match
are directly included in df_output.
as_tibble() ensures the output is in tibble format.
III. Step 3: Iterative Selection of Best Matches
else{
df_output = [Link]()
for (i in 1:n_match) {
if (i == 1) {
selected_row = control_df[control_df$rank_dist == 1, ]
} else {
selected_row = remaining_df[[Link](remaining_df$rank_dist), ]
}
A loop selects n_match best matches iteratively.
First Iteration (i == 1):
o Selects the row where rank_dist == 1 (the smallest rank, meaning the closest
match).
Subsequent Iterations (i > 1):
o Uses [Link](remaining_df$rank_dist), which returns the index of the
minimum value in rank_dist for remaining_df.
IV. Step 4: Filtering Out Controls Within n_window Hours
df_output = rbind(df_output, selected_row)
selected_time = selected_row$bw_hour
remaining_df = if (i == 1) control_df else remaining_df
remaining_df = remaining_df %>%
filter(bw_hour > selected_time + hours(n_window) |
bw_hour < selected_time - hours(n_window))
}
}
The selected row is appended to df_output.
remaining_df is updated to exclude rows within n_window hours of the selected row to
ensure temporal spacing between matches.
V. Answers to Specific Questions
1. Why does the first iteration use rank_dist == 1, while others use
[Link](rank_dist)?
o rank_dist == 1 ensures the absolute closest match is chosen in the first
iteration.
o [Link](rank_dist) in subsequent iterations selects the next-best match from
remaining_df, ensuring it follows the filtering criteria.
2. How does [Link](rank_dist) handle ties in rank_dist?
o [Link]() returns the first occurrence of the minimum value.
o Since frank(..., [Link] = "first") already ranks ties based on their
order in the dataset, [Link]() respects this order.
VI. Modifying the Code to Keep the Average of All Selected Controls
Instead of appending each selected row to df_output, we can compute the average of all
selected controls at the end:
VII. Modified Code
if (!best_match_restriction){
df_output = control_df[rank_dist <= n_match] %>%
summarise(across(where([Link]), mean, [Link] = TRUE))
} else{
df_selected = [Link]()
for (i in 1:n_match) {
if (i == 1) {
selected_row = control_df[control_df$rank_dist == 1, ]
} else {
selected_row = remaining_df[[Link](remaining_df$rank_dist), ]
}
df_selected = rbind(df_selected, selected_row)
selected_time = selected_row$bw_hour
remaining_df = if (i == 1) control_df else remaining_df
remaining_df = remaining_df %>%
filter(bw_hour > selected_time + hours(n_window) |
bw_hour < selected_time - hours(n_window))
}
# Compute the mean for numeric columns
df_output = df_selected %>% summarise(across(where([Link]), mean, [Link]
= TRUE))
}
VIII. What This Does
For best_match_restriction = FALSE:
o Instead of keeping all rows, it calculates the mean across numeric columns.
For best_match_restriction = TRUE:
o Collects selected rows in df_selected, then computes the average across
numeric columns.
Let me know if you need further refinements! 🚀