Logical operations
Comparisons, conditions, and filtering
Denis O’Meally
City of Hope
By the end
You should be able to:
- recognise that comparisons return
TRUE, FALSE, or NA;
- identify missing measurements and combine logical conditions;
- use a logical condition to filter rows and inspect the selected IDs;
- use one logical value in a simple
if/else decision;
- recognise how a working filter can become a small function; and
- follow a supplied loop that repeats the filter.
Mouse trial
Which treated mice gained at least 3 g?
We need three columns:
mouse_id
treatment
weight_change_g
Weight change
Which measurements are required?
mouse_trial |>
select(
mouse_id,
treatment,
baseline_weight_g,
final_weight_g,
weight_change_g
) |>
slice(c(8, 12, 31, 37))
# A tibble: 4 × 5
mouse_id treatment baseline_weight_g final_weight_g weight_change_g
<chr> <chr> <dbl> <dbl> <dbl>
1 M008 treatment 22.9 26.1 3.20
2 M012 control NA 25 NA
3 M031 treatment 25.6 NA NA
4 M037 treatment 28 34.1 6.1
An unavailable baseline or final weight produces an unavailable change.
Missing values
Which records are missing a required weight?
trial_with_missing_check <- mouse_trial |>
mutate(
missing_required_weight = is.na(baseline_weight_g) |
is.na(final_weight_g)
)
trial_with_missing_check |>
select(
mouse_id,
baseline_weight_g,
final_weight_g,
missing_required_weight
) |>
slice(c(8, 12, 31, 37))
# A tibble: 4 × 4
mouse_id baseline_weight_g final_weight_g missing_required_weight
<chr> <dbl> <dbl> <lgl>
1 M008 22.9 26.1 FALSE
2 M012 NA 25 TRUE
3 M031 25.6 NA TRUE
4 M037 28 34.1 FALSE
| means logical OR. The result is TRUE when either condition is true.
Filtering rows
How do we keep records with both weights?
complete_mouse_records <- trial_with_missing_check |>
filter(!missing_required_weight)
complete_mouse_records |>
summarise(rows = n())
# A tibble: 1 × 1
rows
<int>
1 46
! means logical NOT. It reverses TRUE and FALSE.
filter() retains TRUE rows. Rows with FALSE or NA are not retained.
Comparisons
What does “at least 3 g” return?
c(2.5, 3.0, 3.5, NA) >= 3
| 2.5 g |
? |
| 3.0 g |
? |
| 3.5 g |
? |
| unavailable |
? |
Comparisons
What does “at least 3 g” return?
c(2.5, 3.0, 3.5, NA) >= 3
| 2.5 g |
FALSE |
| 3.0 g |
TRUE |
| 3.5 g |
TRUE |
| unavailable |
NA |
Comparisons
Does exactly 3.0 g meet the condition?
“At least 3.0 g” translates to >= 3.
Conditional execution
Which branch will run?
current_weight_change_g <- 3
if (current_weight_change_g >= 3) {
"include"
} else {
"exclude"
}
What will R return?
Conditional execution
Which branch will run?
current_weight_change_g <- 3
if (current_weight_change_g >= 3) {
"include"
} else {
"exclude"
}
if evaluates one logical value and runs one branch.
Comparing text
Which complete mice received treatment?
mouse_conditions <- complete_mouse_records |>
mutate(
received_treatment = treatment == "treatment"
)
mouse_conditions |>
count(treatment, received_treatment)
# A tibble: 2 × 3
treatment received_treatment n
<chr> <lgl> <int>
1 control FALSE 25
2 treatment TRUE 21
== means equal to. != means not equal to.
Comparing numbers
Which complete mice gained at least 3 g?
mouse_conditions <- mouse_conditions |>
mutate(
gained_at_least_3_g = weight_change_g >= 3
)
mouse_conditions |>
count(gained_at_least_3_g)
# A tibble: 2 × 2
gained_at_least_3_g n
<lgl> <int>
1 FALSE 41
2 TRUE 5
The comparison is now attached to each complete mouse record.
Combining conditions
When is AND true?
| M001 |
TRUE |
FALSE |
? |
| M008 |
TRUE |
TRUE |
? |
| M048 |
FALSE |
FALSE |
? |
received_treatment & gained_at_least_3_g
Combining conditions
When is AND true?
| M001 |
TRUE |
FALSE |
FALSE |
| M008 |
TRUE |
TRUE |
TRUE |
| M048 |
FALSE |
FALSE |
FALSE |
received_treatment & gained_at_least_3_g
& means logical AND.
Combining conditions
How many complete records meet both?
mouse_conditions <- mouse_conditions |>
mutate(
meets_both_conditions = received_treatment &
gained_at_least_3_g
)
mouse_conditions |>
count(meets_both_conditions)
# A tibble: 2 × 2
meets_both_conditions n
<lgl> <int>
1 FALSE 41
2 TRUE 5
Five complete records meet both conditions.
Filtering rows
Which mice meet both conditions?
treated_mice_meeting_gain_threshold <- mouse_conditions |>
filter(meets_both_conditions) |>
select(mouse_id, treatment, weight_change_g)
treated_mice_meeting_gain_threshold
# A tibble: 5 × 3
mouse_id treatment weight_change_g
<chr> <chr> <dbl>
1 M008 treatment 3.20
2 M037 treatment 6.1
3 M041 treatment 3.5
4 M042 treatment 3.6
5 M043 treatment 3.6
The output contains five rows and five mouse IDs.
Functions
Which operation do we want to reuse?
mouse_trial |>
dplyr::filter(
treatment == "treatment",
weight_change_g >= 3
)
This is the filter we have already used.
dplyr::filter() explicitly identifies the tidyverse function.
Functions
How do we give the filter a reusable name?
filter_treated_mice_by_weight_gain <- function(
mouse_data,
minimum_weight_gain_g
) {
mouse_data |>
dplyr::filter(
treatment == "treatment",
weight_change_g >= minimum_weight_gain_g
)
}
Functions
Does it reproduce the five-row result?
filter_treated_mice_by_weight_gain(
mouse_trial,
minimum_weight_gain_g = 3
) |>
select(mouse_id, treatment, weight_change_g)
# A tibble: 5 × 3
mouse_id treatment weight_change_g
<chr> <chr> <dbl>
1 M008 treatment 3.20
2 M037 treatment 6.1
3 M041 treatment 3.5
4 M042 treatment 3.6
5 M043 treatment 3.6
The call reproduces the five-row result.
Iteration
What happens when the filter is repeated?
for (minimum_weight_gain_g in c(2, 3, 4)) {
selected_mice <- filter_treated_mice_by_weight_gain(
mouse_trial,
minimum_weight_gain_g
)
print(nrow(selected_mice))
}
How many times will the body run? What should happen to the row count?
Iteration
What happens when the filter is repeated?
for (minimum_weight_gain_g in c(2, 3, 4)) {
selected_mice <- filter_treated_mice_by_weight_gain(
mouse_trial,
minimum_weight_gain_g
)
print(nrow(selected_mice))
}
Hands-on exercise
How do you open the exercise?
In the BIOSCI504 course Project, run:
BIOSCI504::copy_template("explicit-analytical-rules")
Then open:
exercises/explicit-analytical-rules/analysis.qmd
Hands-on exercise
What will you do?
You will:
- inspect the relevant mouse-trial columns;
- create and inspect logical conditions;
- filter the treated mice meeting the gain threshold;
- complete the small filtering function; and
- run the supplied loop at three thresholds.
Restart R or RStudio, render again, and inspect analysis.html.
Questions