This figure accompanies the paper: Self-reported sleep health is more than a combination of multiple objective sleep measures. Each graph displays the cube at the constant median value for the listed sleep dimension.
This cube is shown in Figure 2.
# linear model for cube visualization
fit_cube <- lm(RU_SATED_c ~
# linear terms
duration + regularity + efficiency + midpoint +
# 2 way interactions
midpoint*duration + regularity*duration + midpoint*regularity +
efficiency*duration + efficiency*midpoint + efficiency*regularity +
# 3 way interactions
midpoint*(regularity)*duration +
midpoint*(efficiency)*duration +
midpoint*(efficiency)*regularity +
duration*(efficiency)*regularity +
# 4 way interaction
duration*(efficiency)*regularity*(midpoint) +
# quadratic terms
I(midpoint^2) + I(regularity^2) + I(duration^2) + I(efficiency^2),
data = snb_ru_sated)
#### Example cube code for midpoint @ 2am (-1) ##############
## Make sequence of possible duration, efficiency, and regularity (we used approx 2.5th and 97.5th percentile as cutoffs)
### duration and regularity are sequenced by 0.5 hours and se is sequenced by 5%
dur_seq <- data.frame(seq(4.5, 10, by = 0.5))
se_seq <- data.frame(seq(65, 90, by = 5))
reg_seq <- data.frame(seq(-3.5, 0, by = 0.5))
## Set constant value for midpoint
mid_const <- -1
# join all sequences together to have a row for each unique combination
seq_dat <- cross_join(dur_seq,se_seq) %>%
cross_join(reg_seq) %>%
mutate(midpoint= mid_const) %>%
#rename variables to match our variable names
dplyr::rename(duration = `seq.4.5..10..by...0.5.`,
efficiency = `seq.65..90..by...5.`,
regularity = `seq..3.5..0..by...0.5.`)
# predict Ru-SATED values across sequence combinations based on our model from above (fit_cube)
seq_dat$rusated_pred <- predict(fit_cube, new = seq_dat)
# use plotly package to plot data in 3D with color
cube_plot <- plot_ly(data = seq_dat,
#call data for x, y and z axis
x=seq_dat$efficiency, y=seq_dat$duration, z=seq_dat$regularity,
#visualization settings
type="scatter3d", mode="markers", alpha = 1, alpha_stroke = 1,
#set color to predicted Ru-SATED values
color =seq_dat$rusated_pred,
#set color min and max to min and max of predicted values
marker = list(cmin = 12, cmax = 17))%>%
#add title, axis title, and legend title
layout(
title = 'Midpoint 2am',
scene = list(xaxis = list(title = 'Efficiency'),
yaxis = list(title = 'Duration (Hrs)'),
zaxis = list(title = 'Regularity')),
annotations = list(
x = 1.13,
y = 1.05,
text = 'Ru-SATEDc',
xref = 'paper',
yref = 'paper',
showarrow = FALSE))