Code
Author
Sergio Uribe
Modified
July 19, 2024
Data summary
Name |
df |
Number of rows |
45 |
Number of columns |
21 |
_______________________ |
|
Column type frequency: |
|
character |
1 |
numeric |
20 |
________________________ |
|
Group variables |
None |
Variable type: character
skim_variable |
n_missing |
complete_rate |
min |
max |
empty |
n_unique |
whitespace |
|---|---|---|---|---|---|---|---|
sex |
0 |
1 |
1 |
1 |
0 |
2 |
0 |
Variable type: numeric
skim_variable |
n_missing |
complete_rate |
mean |
sd |
p0 |
p25 |
p50 |
p75 |
p100 |
hist |
|---|---|---|---|---|---|---|---|---|---|---|
id |
0 |
1 |
23.00 |
13.13 |
1.00 |
12.00 |
23.00 |
34.00 |
45.00 |
▇▇▇▇▇ |
age |
0 |
1 |
27.18 |
6.39 |
19.00 |
22.00 |
26.00 |
32.00 |
48.00 |
▇▆▃▂▁ |
right_t1 |
0 |
1 |
2914.66 |
664.07 |
1861.08 |
2545.01 |
2937.47 |
3222.95 |
5489.98 |
▅▇▃▁▁ |
left_t1 |
0 |
1 |
2973.87 |
745.97 |
1711.80 |
2583.59 |
2888.19 |
3268.36 |
5868.12 |
▃▇▂▁▁ |
right_t2 |
0 |
1 |
763.00 |
366.62 |
259.93 |
490.07 |
707.00 |
950.59 |
1875.61 |
▇▅▅▁▁ |
left_t2 |
0 |
1 |
773.06 |
355.35 |
225.07 |
459.18 |
765.47 |
961.36 |
1860.44 |
▇▇▇▁▁ |
right_t3 |
0 |
1 |
29.45 |
79.52 |
0.20 |
5.64 |
12.00 |
24.05 |
539.65 |
▇▁▁▁▁ |
left_t3 |
0 |
1 |
48.99 |
123.73 |
0.00 |
2.38 |
12.51 |
35.26 |
793.92 |
▇▁▁▁▁ |
t1 |
0 |
1 |
5888.53 |
1356.70 |
3775.51 |
5021.25 |
5726.59 |
6441.41 |
11358.10 |
▅▇▂▁▁ |
t2 |
0 |
1 |
1536.06 |
689.20 |
548.93 |
1104.31 |
1452.65 |
1908.64 |
3736.05 |
▆▇▅▁▁ |
t3 |
0 |
1 |
78.45 |
198.29 |
1.58 |
19.93 |
27.47 |
64.44 |
1333.57 |
▇▁▁▁▁ |
right_t1_abs |
0 |
1 |
2914.66 |
664.07 |
1861.08 |
2545.01 |
2937.47 |
3222.95 |
5489.98 |
▅▇▃▁▁ |
right_t2_abs |
0 |
1 |
2151.66 |
475.49 |
1358.05 |
1883.11 |
2078.86 |
2328.23 |
3950.22 |
▃▇▂▁▁ |
right_t3_abs |
0 |
1 |
2122.21 |
475.62 |
1349.31 |
1861.97 |
2041.48 |
2211.29 |
3933.79 |
▅▇▂▁▁ |
left_t1_abs |
0 |
1 |
2973.87 |
745.97 |
1711.80 |
2583.59 |
2888.19 |
3268.36 |
5868.12 |
▃▇▂▁▁ |
left_t2_abs |
0 |
1 |
2200.80 |
551.10 |
1389.42 |
1848.22 |
2039.43 |
2359.32 |
4252.87 |
▇▇▂▁▁ |
left_t3_abs |
0 |
1 |
2151.81 |
556.29 |
1300.68 |
1782.45 |
2009.97 |
2354.87 |
4223.79 |
▅▇▂▁▁ |
t1_abs |
0 |
1 |
5888.53 |
1356.70 |
3775.51 |
5021.25 |
5726.59 |
6441.41 |
11358.10 |
▅▇▂▁▁ |
t2_abs |
0 |
1 |
4352.47 |
985.46 |
3062.08 |
3743.90 |
4219.50 |
4605.16 |
8203.09 |
▇▇▁▁▁ |
t3_abs |
0 |
1 |
4274.02 |
991.59 |
2991.13 |
3618.55 |
4034.38 |
4555.02 |
8157.58 |
▇▆▂▁▁ |
Absolute Changes in Volume by Time
Time |
n |
median |
range |
max |
min |
mean |
sd |
|---|---|---|---|---|---|---|---|
t1 |
45 |
5726.59 |
1420.16 |
11358.10 |
3775.51 |
5888.53 |
1356.70 |
t2 |
45 |
4219.50 |
861.26 |
8203.09 |
3062.08 |
4352.47 |
985.46 |
t3 |
45 |
4034.38 |
936.47 |
8157.58 |
2991.13 |
4274.02 |
991.59 |
Relative Change in Volume by Time
time |
n |
mean |
sd |
se |
lower_ci |
upper_ci |
|---|---|---|---|---|---|---|
1 week |
45 |
100.0 |
0.0 |
0.0 |
100.0 |
100.0 |
4 months |
45 |
74.6 |
8.3 |
1.2 |
72.1 |
77.0 |
12 months |
45 |
73.3 |
9.1 |
1.4 |
70.6 |
75.9 |
Difference in relative_change by age?
p-value |
|||
|---|---|---|---|
Age |
0.06 |
-0.38, 0.49 |
0.8 |
Sex |
|
|
|
F |
— |
— |
|
M |
33 |
-1.9, 69 |
0.063 |
Age * Sex |
|
|
|
Age * M |
-1.4 |
-2.7, -0.20 |
0.024 |
1 CI = Confidence Interval |
|||
# A tibble: 11 × 1t3<dbl>1 43.72 63.63 66.14 70.45 73.26 75.07 76.38 78.09 80.010 84.411 87.6
10% of patients showed volume loss of less than 15%, which means that the final implant volume is more than anticipated. 20% of patients showed volume loss of more than 35% which means that the final implant volume is considerably less than anticipated and 5% of patients lost 45% or more of the initial volume. Furthermore, when analysing symmetry of volume loss we can see that 20% of patients had more than 7% difference in volume loss for one of the sides, this difference can cause asymmetrical malar zones.
# A tibble: 1 × 1change<dbl>1 4.44
Correct answer: 4.4% of patients showed volume loss of less than 15%
20% of patients showed volume loss of more than 35%
# A tibble: 1 × 1change<dbl>1 13.3
Correct answer: 13.3% of patients showed volume loss of more than 35%
5% of patients lost 45% or more of the initial volume
# A tibble: 1 × 1change<dbl>1 4.44
Correct answer: 4.4% of patients showed volume loss of more than 45%
Furthermore, when analysing symmetry of volume loss we can see that 20% of patients had more than 7% difference in volume loss for one of the sides,
calculate the difference in volume per side
# A tibble: 45 × 3id right_change left_change<dbl> <dbl> <dbl>1 1 28.3 28.02 2 21.0 20.63 3 13.1 12.54 4 15.7 14.95 5 22.8 21.96 6 25.4 26.47 7 14.5 16.08 8 19.3 21.09 9 30.6 28.810 10 29.9 28.1# ℹ 35 more rows
Now compare the difference between sides
# A tibble: 45 × 2id difference_between_sides<dbl> <dbl>1 1 0.3252 2 0.4233 3 0.6324 4 0.8135 5 0.8876 6 1.057 7 1.518 8 1.749 9 1.7710 10 1.80# ℹ 35 more rows
Now count how many > 7%
# A tibble: 1 × 1change<dbl>1 17.8
Correct answer: Furthermore, when analysing symmetry of volume loss we can see that 17.7% of patients had more than 7% difference in volume loss for one of the sides,
---title: "02_EDA"author: "Sergio Uribe"date-modified: last-modifiedformat:html:toc: truetoc-expand: 3code-fold: truecode-tools: trueeditor: visualexecute:echo: falsecache: falsewarning: falsemessage: false---# Packages```{r}pacman::p_load(tidyverse, # tools for data sciencevisdat, #NAsscales,here,skimr, # EDAgtsummary,janitor)``````{r}theme_set(theme_minimal())``````{r}#| output: falsehere::here()```# Dataset```{r}df <- read_csv(READ THE DATA)```## Preliminary EDA```{r}skimr::skim(df)```# Simplify the dataset```{r}# df |># # create all by side and time# pivot_longer(right_t1:left_t3, names_to = "side_time", values_to = "side_volume") |># pivot_longer(t1:t3, names_to = "t_time", values_to = "t_volume") |># pivot_longer(right_t1_abs:left_t3_abs, names_to = "side_time_abs", values_to = "side_volume_abs") |># pivot_longer(t1_abs:t3_abs, names_to = "t_time_abs", values_to = "t_volume_abs")``````{r}#| output: falsedf_long <- df |>pivot_longer(cols = starts_with("right_") | starts_with("left_"),names_to = "side_time",values_to = "side_volume") |>pivot_longer(cols = matches("^[t][1-3]_?abs?$"),names_to = "time_abs",values_to = "volume_abs") |>pivot_longer(t1:t3, names_to = "time", values_to = "volume")```# Exploratory Data Analysis# DEMOGRAPHICS## Table 1 Patients and age```{r}df |>select(Age = age,Sex = sex) |>gtsummary::tbl_summary()```# ABSOLUTE CHANGES## Absolute Change in Volume by Time```{r}df |>select(id:age,t1:t3) |># calculate the change in volumemutate(t1 = t1,t2 = t1 - t2,t3 = t2 - t3) |>pivot_longer(-c(id:age),names_to = "time",values_to = "value") |>mutate(time = recode(time,t1 = "1 week",t2 = "4 months",t3 = "12 months")) |>mutate(time = fct_relevel(time, "1 week", "4 months", "12 months")) |># # calculate the relative change# group_by(id) %>%# arrange(id, time) %>%# mutate(relative_change = (value / lag(value) - 1) * 100) %>%# ungroup() |>### filter(!is.na(relative_change)) |># select(-c(value)) |>ggplot(aes(x = time,y = value,# size = age,color = sex, # by sexgroup = id)) +geom_line(alpha = .3) +geom_point(alpha = .3) +labs(title = "Absolute Change in Volume by Time",x = "Time",color = "Sex",y = "Volume (mm3)") +# facet_grid(. ~ sex ) + # by sexscale_y_continuous(labels = scales::comma) # scale_y_log10(labels = scales::comma)```### Absolute changes by time violin plot```{r}df |>select(id:age,t1:t3) |># calculate the change in volumemutate(t1 = t1,t2 = t1 - t2,t3 = t2 - t3) |>pivot_longer(-c(id:age),names_to = "Time") |>mutate(Time = recode(Time,t1 = "1 week",t2 = "4 months",t3 = "12 months")) |>mutate(Time = fct_relevel(Time, "1 week", "4 months", "12 months")) |>ggplot(aes(x = Time,# color = sex,# group = id,y = value)) +geom_violin() +geom_jitter(alpha = .2, width = .2) +geom_boxplot(width = .1, alpha = 0.5) +# geom_line(aes(group = id, color = as.factor(id)), alpha = 0.1, size = 0.7) +# scale_color_viridis_d(begin = 0.5, end = 0.9, option = "C") +# geom_line(aes(group = id), alpha = 0.1) + # this line shows each patient. Check the outliers shown in 12scale_y_continuous(labels = scales::comma) +labs(title = "Absolute Changes in Volume by Time",x = "Time",y = "Total Bilateral Volume (mm3)")``````{r}df |>select(id:age,t1:t3) |># calculate the change in volumemutate(t1 = t1,t2 = t1 - t2,t3 = t2 - t3) |>pivot_longer(-c(id:age),names_to = "Time") |>group_by(Time) |>summarise(n = n(),median = median(value, na.rm = TRUE),range = IQR(value, na.rm = TRUE),max = max(value, na.rm = TRUE),min = min(value, na.rm = TRUE),mean = mean(value, na.rm = TRUE),sd = sd(value, na.rm = TRUE)) |>mutate_if(is.numeric, round, 2) |>knitr::kable(caption = "Absolute Changes in Volume by Time")``````{r}# Graph Absolute change in volume by time# df |># select(id, sex, age, t1_abs:t3_abs) |># pivot_longer(-c(id:age)) |># mutate(name = recode(name,# t1_abs = "1 week",# t2_abs = "4 months",# t3_abs = "12 months")) |># group_by(name) |># summarise(n = n(),# mean = mean(value),# sd = sd(value)) |># mutate_if(is.numeric,# ~round(., 2)) |># knitr::kable(caption = "Absolute Changes in Volume by Time")``````{r}# df |># select(id, sex, age, t1_abs:t3_abs) |># pivot_longer(-c(id:age)) |># mutate(name = recode(name,# t1_abs = "1 week",# t2_abs = "4 months",# t3_abs = "12 months")) |># ggplot(aes(x = name,# # color = sex,# y = value)) +# geom_violin() +# geom_jitter(alpha = .2, width = .2) +# geom_boxplot(width = .1, alpha = 0.5) +# scale_y_continuous(labels = scales::comma) +# labs(title = "Absolute Changes in Volume by Time",# x = "Time",# y = "Volume (mm3)")```# RELATIVE CHANGES## Relative change in volume by time```{r}df |>select(id, sex, t1_abs:t3_abs) |># create the relative change variablemutate(relative_change = ((t3_abs - t1_abs) / t1_abs)*100) |>ggplot(aes(x = relative_change)) +geom_histogram(bins = 20) +labs(title = "Relative Change in Volume by Time",x = "Relative Change",y = "Frequency") +scale_x_continuous(labels = scales::percent_format(scale = 1)) +xlim(-75, 0)```## Relative change in volume by time```{r}df |>select(id, sex, age, t1:t3) |># what is the volume at each time point?mutate(t2 = t1 - t2,t3 = t2 - t3) |># relative changemutate(t2 = (t2 / t1) * 100,t3 = (t3 / t1) * 100) |>mutate(t1 = 100) |>pivot_longer(-c(id:age),names_to = "time") |>mutate(time = recode(time,t1 = "1 week",t2 = "4 months",t3 = "12 months") ) |>mutate(time = fct_relevel(time,"1 week","4 months")) |>ggplot(aes(x = time,y = value,group = id)) +geom_line(alpha = .1) +geom_jitter(alpha = .2, width = .2) +labs(title = "Relative Change in Volume by Time",x = "Time",y = "Relative Change") +scale_y_continuous(labels = scales::percent_format(scale = 1))```### Table Relative Change in Volume by Time```{r}df |>select(id, sex, age, t1:t3) |># what is the volume at each time point?mutate(t2 = t1 - t2,t3 = t2 - t3) |># relative changemutate(t2 = (t2 / t1) * 100,t3 = (t3 / t1) * 100) |>mutate(t1 = 100) |>pivot_longer(-c(id:age),names_to = "time") |>mutate(time = recode(time,t1 = "1 week",t2 = "4 months",t3 = "12 months")) |>mutate(time = fct_relevel(time,"1 week","4 months")) |>group_by(time) |>summarise(n = n(),mean = mean(value, na.rm = TRUE),sd = sd(value, na.rm = TRUE),n = n(),se = sd / sqrt(n), # Calculate Standard Errorlower_ci = mean - 1.96 * se, # Lower bound of the 95% CIupper_ci = mean + 1.96 * se ) |> # Upper bound of the 95% CImutate_if(is.numeric, round, 1) |>knitr::kable(caption = "Relative Change in Volume by Time")```## Relative change by Sex```{r}df |>select(id,Sex = sex,t1_abs:t3_abs) |># create the relative change variablemutate(relative_change = ((t3_abs - t1_abs) / t1_abs)*100) |>ggplot(aes(y = relative_change,x = Sex)) +geom_violin() +geom_jitter(alpha = .2, width = .2) +geom_boxplot(width = .1, alpha = 0.5) +labs(title = "Relative Change at 12 months in Volume",x = "Sex",y = "Relative Change") +scale_y_continuous(labels = scales::percent_format(scale = 1)) +ylim(-75, 0)``````{r}## Difference in relative change by sex?# df |># select(Sex = sex,# t1_abs:t3_abs) |># # create the relative change variable# mutate(relative_change = ((t3_abs - t1_abs) / t1_abs)*100) |># select(Sex, relative_change) |># gtsummary::tbl_summary(by = Sex) |># gtsummary::add_ci() |># gtsummary::add_p()``````{r}# df |># select(Sex = sex,# t1_abs:t3_abs) |># # create the relative change variable# mutate(relative_change = ((t3_abs - t1_abs) / t1_abs)*100) |># select(Sex, relative_change) |># with(lm(relative_change ~ Sex)) |># gtsummary::tbl_regression()```## Relative change by Age```{r}df |>select(id,Age = age,t1_abs:t3_abs) |># create the relative change variablemutate(relative_change = ((t3_abs - t1_abs) / t1_abs)*100) |>ggplot(aes(y = relative_change,x = Age)) +geom_point() +geom_smooth() +labs(title = "Relative Change at 12 months in Volume by Age",x = "Age",y = "Relative Change")```Difference in relative_change by age?```{r}# df |># select(age,# t1_abs:t3_abs) |># # create the relative change variable# mutate(relative_change = ((t3_abs - t1_abs) / t1_abs)*100) |># select(age, relative_change) |># with(lm(relative_change ~ age)) |># gtsummary::tbl_regression()```# REGRESSION ANALYSIS## Table 2 Difference in relative change by age and sex?```{r}df |>select(age,sex,t1_abs:t3_abs) |># create the relative change variablemutate(relative_change = ((t3_abs - t1_abs) / t1_abs)*100) |>select(Age = age,Sex = sex,relative_change) |>with(lm(relative_change ~ Age + Sex + Sex:Age)) |>gtsummary::tbl_regression()```# ANALYSIS BY SIDE```{r}df |>select(id:age,right_t1_abs = right_t1,right_t2_abs:left_t3_abs) |>pivot_longer(-c(id:age),names_to = "side_time_abs",values_to = "value") |>separate(side_time_abs, into = c("side", "time", "abs"), sep = "_", remove = TRUE) |>mutate(time = recode(time,t1 = "1 week",t2 = "4 months",t3 = "12 months")) |>mutate(time= fct_relevel(time,"1 week","4 months","12 months")) |>select(-abs) |>ggplot(aes(x = time,y = value,# color = sex,group = id)) +geom_line(alpha = .3) +geom_point(alpha = .3) +scale_y_continuous(labels = scales::comma) +facet_grid(. ~ side ) +labs(title = "Change in Volume by Time and Side",x = "Time",y = "Volume (mm3)")```# Additional```{r}df |>select(id, t1:t3) |># what is the volume at each time point?mutate(t2 = t1 - t2,t3 = t2 - t3) |># relative changemutate(t2 = (t2 / t1) * 100,t3 = (t3 / t1) * 100) |>mutate(t1 = 100) |>arrange(desc(t3)) |># ggplot(aes(x = t3)) +# geom_histogram(bins = 10) +# xlim(c(0, 100))summarise(across(t3, quantile, probs = seq(0, 1, 0.1)))```10% of patients showed volume loss of less than 15%, which means that the final implant volume is more than anticipated. 20% of patients showed volume loss of more than 35% which means that the final implant volume is considerably less than anticipated and 5% of patients lost 45% or more of the initial volume. Furthermore, when analysing symmetry of volume loss we can see that 20% of patients had more than 7% difference in volume loss for one of the sides, this difference can cause asymmetrical malar zones.```{r}total_rows <- nrow(df)df |>mutate(percentage_change = (abs((t3_abs - t1_abs) / t1_abs)) * 100) |>select(id, percentage_change) |>filter(percentage_change < 15) |>summarise(change = n() / total_rows * 100)```**Correct answer: 4.4% of patients showed volume loss of less than 15%**20% of patients showed volume loss of more than 35%```{r}df |>mutate(percentage_change = (abs((t3_abs - t1_abs) / t1_abs)) * 100) |>select(id, percentage_change) |>filter(percentage_change > 35) |>summarise(change = n() / total_rows * 100)```**Correct answer: 13.3% of patients showed volume loss of more than 35%**5% of patients lost 45% or more of the initial volume```{r}df |>mutate(percentage_change = (abs((t3_abs - t1_abs) / t1_abs)) * 100) |>select(id, percentage_change) |>filter(percentage_change > 45) |>summarise(change = n() / total_rows * 100)```**Correct answer: 4.4% of patients showed volume loss of more than 45%**Furthermore, when analysing symmetry of volume loss we can see that 20% of patients had more than 7% difference in volume loss for one of the sides,1. calculate the difference in volume per side```{r}df |>mutate(right_change = abs((right_t3_abs - right_t1_abs)) / right_t1_abs * 100,left_change = abs((left_t3_abs - left_t1_abs)) / left_t1_abs * 100) |>select(id, right_change, left_change)```Now compare the difference between sides```{r}df |>mutate(right_change = abs((right_t3_abs - right_t1_abs)) / right_t1_abs * 100,left_change = abs((left_t3_abs - left_t1_abs)) / left_t1_abs * 100) |>select(id, right_change, left_change) |>mutate(difference_between_sides = abs(right_change - left_change)) |>select(id, difference_between_sides)```Now count how many \> 7%```{r}df |>mutate(right_change = abs((right_t3_abs - right_t1_abs)) / right_t1_abs * 100,left_change = abs((left_t3_abs - left_t1_abs)) / left_t1_abs * 100) |>select(id, right_change, left_change) |>mutate(difference_between_sides = abs(right_change - left_change)) |>select(id, difference_between_sides) |>filter(difference_between_sides > 7) |>summarise(change = n() / total_rows * 100)```**Correct answer: Furthermore, when analysing symmetry of volume loss we can see that 17.7% of patients had more than 7% difference in volume loss for one of the sides,**