Показать код
library(ggdag)
library(ggplot2)
library(dplyr)and what happens when they collide
В статье (De Bosscher et al. 2023) исследовалась связь между занятиями спортом и атеросклерозом. Авторы пишут, что они провели проспективное когортное исследование и показали, что у мужчин, активно занимающихся спортом, оказывается сильнее выражен атеросклероз.
В обсуждении у Алексея Эрлиха в ФБ я спросил, а точно ли это проспективное когортное исследование? Выглядело это, как некая придирка. Как известно, идеальных исследований нет и всегда можно к чему-нибудь придраться. Однако я считаю важным пояснить, почему у меня возник такой вопрос и почему он реально важен. В формате комментария в ФБ это сделать трудновато, поэтому я решил разобрать это здесь.
За подробным обсуждением методов отсылаю читателей к исходной статье. Отмечу лишь самое важное.
У здоровых мужчин, длительно занимающихся спортом, атеросклероз выражен сильнее, чем у тех, кто просто ведет здоровый образ жизни.
Проспективное когортное исследование подразумевает, что сначала набирают пациентов, оценивают интересующий фактор (воздействие, exposure), а затем наблюдают, как будут развиваться исходы. Здесь взяли пациентов, оценили воздействие задним числом? и сразу же оценили исходы с помощью КТ-ангиографии.
То есть исследование не было проспективным. В момент набора пациентов исходы уже были.
Может быть оно было ретроспективным когортным? В ретроспективном когортном появлением исходов оценивают задним числом, по имеющимся записям. Но тут все исходы оценивали уже после набора пациентов. То есть это и не ретроспективное когортное исследование.
Это кросс-секционное исследование: все исходы и воздействия оценивали одномоментно.
По-видимому фраза о проспективном когортном исследовании появилась из исходного протокола (De Bosscher et al. 2021): изначально планировалось проследить этих пациентов в течение двух лет и регистрировать клинические исходы. Эта часть исследования действительно была бы проспективной когортной (и, возможно, еще будет), но в нашей публикации эти данные не представлены.
Кросс-секционное исследование – это совсем не плохо. Но у него есть недостаток: мы исследуем только выживших. Если предположить, что те, кто мало занимался спортом, чаще умирают, то мы получим смещенную выборку: те, кто умер, не будут регистрироваться на сайте. При этом логично предположить, что у умерших атеросклероз был более выраженным, чем у выживших. Однако в целом это были довольно здоровые молодые люди (средний возраст 55 лет) и нет оснований думать, что многие из них могли умереть. Но проблема в том, что отбор был не только по тому, кто жив, но и по тому, кто здоров. И тут давайте перейдем к симуляции.
Рассмотрим всего три показателя: занятия спортом, индекс массы тела и атеросклероз. Сделаем следующие предположения относительно связи этих факторов:
Тут нет цели полностью имитировать реальность, мы хотим лишь посмотреть, как такой дизайн исследования может повлиять на результаты в похожей ситуации.
Вот так будет выглядеть граф причинно-следственных связей для нашей симуляции:
library(ggdag)
library(ggplot2)
library(dplyr)theme_set(theme_dag())
coords <- list(
x = c(sport = 1, bmi = 2, risk = 3, athero = 4),
y = c(sport = .5, bmi = .5, risk = .5, athero = .5)
)
dag <- dagify(bmi ~ risk,
athero ~ risk,
bmi ~ sport,
labels = c(
"bmi" = "Obesity",
"risk" = "CV risk",
"sport" = "Sport",
"athero" = "Atherosclerosis"
),
latent = "sport",
exposure = "risk",
outcome = "athero",
coords = coords
)
ggdag(dag, text = F) +
geom_dag_label_repel(aes(label = label), direction = "y", seed = 9, size = 3) Теперь создадим симуляционный датасет и посмотрим, что получится. Интенсивность занятий спортом (\(sport\)) и неизвестный фактор риска (\(risk\)) атеросклероза и индекса массы тела у нас будут распределены нормально. Зависимость атеросклероза (\(athero\)) от фактора риска и индекса массы тела (\(bmi\)) от фактора риска и спорта для простоты будет экспоненциальной с добавлением небольшого случайного шума.
set.seed(10)
df <- data.frame(risk = rnorm(1000), sport = rnorm(1000))
df$athero <- exp(df$risk) + rnorm(1000, 0, .5)
df$bmi <- exp(df$risk) + 2*exp(-df$sport) + rnorm(1000, 0, .5)Вот так будут выглядеть графики зависимости этих показетелей друг от друга:
noticks_theme <- theme(axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank())
df %>%
ggplot(aes(x=risk, y=bmi)) +
geom_point() +
labs(x="Фактор риска", y="Индекс массы тела") +
theme_bw() + noticks_themedf %>%
ggplot(aes(x=risk, y=athero)) +
geom_point() +
labs(x="Фактор риска", y="Атеросклероз") +
theme_bw() + noticks_themedf %>%
ggplot(aes(x=sport, y=bmi)) +
geom_point() +
labs(x="Спорт", y="Индекс массы тела") +
theme_bw() + noticks_themedf %>%
ggplot(aes(x=sport, y=athero)) +
geom_point() +
labs(x="Спорт", y="Атеросклероз") +
theme_bw() + noticks_themeКак видно на последнем графике, никакой зависимости между спортом и атеросклерозом нет, как и задано в симуляции. Чтобы было похоже на исследование, разобьем спорт на три категории (по квантилям) и посмотрим еще раз:
df <- df %>%
mutate(
sportq = case_when(
sport < quantile(sport, .33) ~ "low",
sport < quantile(sport, .66) ~ "medium",
T ~"high"
)
)
df$sportq <- factor(df$sportq, levels=c('low', 'medium', 'high'))
df %>%
ggplot(aes(x=sportq, y=athero)) +
geom_col(aes(fill=sportq), show.legend = FALSE) +
labs(x="Интенсивность занятий спортом", y="Атеросклероз") +
theme_bw()Все чисто.
До сих пор все у нас было хорошо. Зависимости между спортом и атеросклерозом не было в модели и не появилось в результатах симуляции. Но вспомним, что делали авторы исследования. Они не включали пациентов с ожирением (индекс массы тела > 27,2). Давайте попробуем тоже так сделать: действительно, мы же хотим исследовать только здоровых. Давайте отсечем верхний квартиль по ИМТ и обзовем это “ожирением”. И посмотрим как это отразится на графике зависимости атеросклероза от интенсивности занятий спортом. Пациентов с ожирением и без обозначим разными цветами.
df <- df %>%
mutate(
obesity = (bmi > quantile(bmi, 0.75))
)
df$obesity <- factor(df$obesity, levels=c(TRUE, FALSE), labels=c("Obese", "Not obese"))
df %>%
ggplot(aes(x=sport, y=athero)) +
geom_point(aes(color=obesity)) +
labs(x="Спорт", y="Атеросклероз") +
theme_bw() + noticks_themeНа этом графике уже можно что-то заподозрить. Но давайте посмотрим столбиковую диаграмму по квантилям только для тех, кто страдает ожирением.
df %>%
filter(obesity != "Obese") %>%
ggplot(aes(x=sportq, y=athero)) +
geom_col(aes(fill=sportq), show.legend = FALSE) +
labs(x="Интенсивность занятий спортом", y="Атеросклероз") +
theme_bw()Это уже гораздо интереснее. Мы всего лишь убрали пациентов с ожирением, как авторы статьи. И сразу получили очень интересный график, как авторы статьи.
Произошла ошибка отбора. Но если использовать язык causal inference, то произошел контроль по коллайдеру. Это частая проблема, когда пытаются сделать коррекцию на факторы, которые не являются конфаундерами. Тут вроде бы ожирение и спорт на диаграмме причинно-следственных связей вообще лежат где-то сбоку от реальной причинно-следственной связи. Но если сделать контроль по ожирению, то открывается (не причинно-следственная) связь между спортом и атеросклерозом.
Берем тот же граф, что вначале и смотрим на связи с и без контроля по ожирению. Цветом обозначен открытый путь – наличие связи.
ggdag_paths(dag, text = FALSE, use_labels = "label", shadow = TRUE, seed=10) А теперь делаем контроль по коллайдеру (ожирение) и у нас открывается некаузальный путь от спорта к атеросклерозу:
ggdag_dseparated(dag,
controlling_for = c("bmi"),
text = FALSE, use_labels = "label", collider_lines = T
)Авторы пишут, что они предприняли специальные усилия, чтобы избежать ошибки отбора:
From all eligible subjects, 605 were sampled at random for inclusion to minimize the risk of selection bias.
По сути они берут случайную подвыборку из исходной выборки. Но это никак не уменьшает ошибку отбора. Если исходная выборка смещена, то и случайная подвыборка из нее будет точно так же смещена.
Дизайн исследования имеет значения.
Отбор/контроль по коллайдеру чреват смещением.
Статья в JAMA (Holmberg and Andersen 2022).
Чуть более продвинутая статья в Epidemiology (Hernán, Hernández-Díaz, and Robins 2004).