Вопрос или проблема
У меня есть данные из кросс-стадии, для которых мне нужно построить несколько графиков. Нет проблем с тем, чтобы нарисовать ‘средний’ график для всех испытуемых, но мне также нужны отдельные графики для каждого испытуемого с наложенными двумя лечениями (Т против R). И еще один вопрос – как назначить идентификатор испытуемого для каждого графика. Ниже приведены данные для 4 испытуемых (может быть больше, до 100).
structure(list(subj = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4), seq = c(2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), prd = c(1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
time = c(0, 0.333, 0.667, 1, 1.333, 1.667, 2, 2.5, 3, 3.5,
4, 6, 8, 12, 24, 48, 0, 0.333, 0.667, 1, 1.333, 1.667, 2,
2.5, 3, 3.5, 4, 6, 8, 12, 24, 48, 0, 0.333, 0.667, 1, 1.333,
1.667, 2, 2.5, 3, 3.5, 4, 6, 8, 12, 24, 48, 0, 0.333, 0.667,
1, 1.333, 1.667, 2, 2.5, 3, 3.5, 4, 6, 8, 12, 24, 48, 0,
0.333, 0.667, 1, 1.333, 1.667, 2, 2.5, 3, 3.5, 4, 6, 8, 12,
24, 48, 0, 0.333, 0.667, 1, 1.333, 1.667, 2, 2.5, 3, 3.5,
4, 6, 8, 12, 24, 48), conc = c(0,
0, 103.041, 301.731, 371.722, 341.099, 326.791, 279.52, 262.657,
234.926, 220.389, 141.804, 112.702, 68.981, 31.9, NA, 0,
0, 0, 0, 11, 24.436, 57.257, 122.065, 159.702, 271.629, 402.88,
154.535, 126.576, 75.999, 33.272, NA, 0, 0, 0, 0, 0, 25.932,
134.108, 257.836, 250.676, 237.466, 248.142, 142.511, 116.839,
66.76, 23.942, NA, 0, 0, 0, 27.992, 78.208, 306.763, 361.578,
303.356, 248.948, 193.574, 184.743, 104.518, 76.36, 44.371,
15.609, NA, 0, 49.073, 356.27, 546.462, 764.171, 822.19,
910.403, 818.073, 687.538, 601.246, 598.949, 301.036, 265.579,
129.278, 55.892, 11.525, 0, 60.115, 316.231, 496.366, 764.952,
1086.271, 982.368, 839.902, 757.569, 622.151, 733.912, 314.365,
242.839, 138.138, 67.617, 15.515, 0, 0, 51.362, 135.969,
253.814, 353.437, 346.998, 314.292, 385.864, 516.589, 627.003,
263.782, 274.407, 127.667, 45.013, NA, 0, 0, 0, 59.682, 237.216,
380.224, 528.946, 523.512, 446.714, 417.835, 352.487, 199.18,
195.568, 99.99, 39.81, NA), drug = c(“T”, “T”, “T”, “T”,
“T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”,
“R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”,
“R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”,
“R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “T”, “T”, “T”, “T”,
“T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”,
“R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”,
“R”, “R”, “R”, “R”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”,
“T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”,
“T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”, “T”,
“R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”, “R”,
“R”, “R”, “R”, “R”)), row.names = c(NA, -128L), class = c(“tbl_df”,
“tbl”, “data.frame”))
Код, который я использую для ‘среднего’ графика, следующий:
data <-
Totalplot |>
group_by(drug, time) |>
summarise(conc = mean(conc, na.rm = TRUE))
plot <-
ggplot(
data = data, aes(x = time, y = conc, color = drug)) +
geom_point(
aes(
group = interaction(drug, time)), alpha = 0.5, shape = 2, position = position_jitter(width = 0.1, height = 0)) +
geom_line(data = data, linewidth = 0.5) +
xlab('Time, h') +
ylab('Drug X plasma conc. ng/ml') +
labs(title="Mean plasma concentration") +
theme_bw()
Используйте lapply
:
subjectsIDs <- unique(Totalplot$subj)
plots <- lapply(subjectIDs, function(x) {
Totalplot %>% filter(subj == x) %>%
ggplot(
aes(x = time, y = conc, color = drug)) +
geom_point(
aes(
group = interaction(drug, time)), alpha = 0.5, shape = 2, position = position_jitter(width = 0.1, height = 0)) +
geom_line(linewidth = 0.5) +
xlab('Time, h') +
ylab('Drug X plasma conc. ng/ml') +
labs(title = paste('Subject', x, 'plasma concentration')) +
theme_bw()
})
Не уверен, что это то, что вы имеете в виду под назначением идентификатора испытуемого для каждого графика, но вы можете назвать каждый элемент списка графиков:
names(plots) <- subjectIDs
Это позволит вам получить доступ к каждому графику так:
plots[["1"]]
Если вы не хотите, чтобы графики для испытуемых без данных на 48 часах имели дополнительное пространство справа, отфильтруйте NA:
subjectsIDs <- unique(Totalplot$subj)
plots <- lapply(subjectsIDs, function(x) {
Totalplot %>% filter(subj == x, !is.na(conc)) %>%
ggplot(
aes(x = time, y = conc, color = drug)) +
geom_point(
aes(
group = interaction(drug, time)), alpha = 0.5, shape = 2, position = position_jitter(width = 0.1, height = 0)) +
geom_line(linewidth = 0.5) +
xlab('Time, h') +
ylab('Drug X plasma conc. ng/ml') +
labs(title = paste('Subject', x, 'plasma concentration')) +
theme_bw()
})
names(plots) <- subjectsIDs
plots[["1"]]
В качестве альтернативы, если вы хотите все графики расположить в сетке:
plot <- Totalplot %>%
ggplot(
aes(x = time, y = conc, color = drug)) +
geom_point(
aes(
group = interaction(drug, time)), alpha = 0.5, shape = 2, position = position_jitter(width = 0.1, height = 0)) +
geom_line(linewidth = 0.5) +
xlab('Time, h') +
ylab('Drug X plasma conc. ng/ml') +
labs(title="Plasma concentration by subject") +
theme_bw() +
facet_wrap(facets = vars(subj))
plot
Ответ или решение
Для того чтобы создать отдельные графики для каждого участника в исследовании с использованием библиотеки ggplot2 в языке программирования R, вам потребуется следовать определенной последовательности шагов. Этот процесс включает агрегацию данных, использование функции lapply
для создания списка графиков и, при необходимости, применение функции facet_wrap
для отображения всех графиков в виде сетки. Давайте рассмотрим это более подробно.
1. Подготовка данных
Прежде всего, убедитесь, что ваши данные находятся в нужном формате. Ваши данные должны включать идентификатор участников (например, subj
), время (time
), концентрацию препарата (conc
) и тип препарата (drug
).
2. Агрегация данных для среднего графика
Вы уже реализовали агрегацию данных, чтобы построить график среднего значения для всех участников. Ваш код для усредненного графика выглядит следующим образом:
data <- Totalplot |>
group_by(drug, time) |>
summarise(conc = mean(conc, na.rm = TRUE))
plot <- ggplot(data, aes(x = time, y = conc, color = drug)) +
geom_point(aes(group = interaction(drug, time)), alpha = 0.5, shape = 2, position = position_jitter(width = 0.1, height = 0)) +
geom_line(data = data, linewidth = 0.5) +
xlab('Time, h') +
ylab('Drug X plasma conc. ng/ml') +
labs(title="Mean plasma concentration") +
theme_bw()
3. Создание отдельных графиков для каждого участника
Теперь для создания отдельных графиков для каждого участника можно использовать функцию lapply
. Вот как это можно сделать:
library(ggplot2)
library(dplyr)
# Получаем уникальные идентификаторы участников
subjectsIDs <- unique(Totalplot$subj)
# Создаем список графиков для каждого участника
plots <- lapply(subjectsIDs, function(x) {
Totalplot %>%
filter(subj == x) %>%
ggplot(aes(x = time, y = conc, color = drug)) +
geom_point(aes(group = interaction(drug, time)), alpha = 0.5, shape = 2, position = position_jitter(width = 0.1, height = 0)) +
geom_line(linewidth = 0.5) +
xlab('Time, h') +
ylab('Drug X plasma conc. ng/ml') +
labs(title = paste('Subject', x, 'plasma concentration')) +
theme_bw()
})
# Назначаем имена графикам
names(plots) <- subjectsIDs
Теперь у вас есть список графиков, где каждый график соответствует участнику. Для доступа к графику конкретного участника можно использовать следующий код:
plots[["1"]] # Получение графика для участника 1
4. Альтернативный способ – использование facet_wrap
Если вы хотите сэкономить место и увидеть все графики на одном экране, вы можете использовать функцию facet_wrap
. Это позволит вам автоматически разделить данные по участникам и построить графики в виде сетки:
plot <- Totalplot %>%
ggplot(aes(x = time, y = conc, color = drug)) +
geom_point(aes(group = interaction(drug, time)), alpha = 0.5, shape = 2, position = position_jitter(width = 0.1, height = 0)) +
geom_line(linewidth = 0.5) +
xlab('Time, h') +
ylab('Drug X plasma conc. ng/ml') +
labs(title="Plasma concentration by subject") +
theme_bw() +
facet_wrap(~ subj)
print(plot)
Этот подход позволит вам визуализировать данные по всем участникам сразу, что создаст более целостное представление о результатах исследования.
Заключение
С помощью методов, описанных выше, вы можете создавать отдельные графики для каждого участника или же комбинировать их в едином пространстве для более удобного анализа и визуализации. Это не только упростит ваш процесс анализа данных, но и сделает результаты более наглядными и доступными для интерпретации. Не забудьте проверить данные на пропуски и убедиться, что они корректны перед визуализацией.