/
insert_or.R
210 lines (199 loc) · 7.27 KB
/
insert_or.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#' @title Insert odds ratios of GAM(M)s into smoothing function
#'
#' @description This function inserts calculated odds ratios of GAM(M)s into a
#' plot of a GAM(M) smoothing function.
#'
#' @import ggplot2
#'
#' @param plot_object A `ggplot` object from [plot_gam()].
#' @param or_object A [data.frame] as returned from [or_gam()].
#' @param values Whether to print predictor value information nearby the
#' inserted vertical lines.
#' @param rect Whether to print a shaded rectangle between the
#' vertical lines.
#' @param arrow Whether to print arrows above the inserted values.
#' @param line_col,line_alpha,line_type,line_size Aesthetics of vertical lines.
#' @param text_col,text_alpha,text_size Aesthetics of inserted values.
#' @param rect_col,rect_alpha Aesthetics of shaded rectangle.
#' @param or_yloc,values_yloc Specifies y-location of inserted odds ratio
#' values. Relative to plotted y-axis range. A positive (negative) value will
#' place the the text higher (lower).
#' @param values_xloc x-axis location/shift of values relative to their vertical
#' line. Default to 2\\% of x-axis range.
#' @param arrow_xloc_r,arrow_xloc_l,arrow_yloc,arrow_length,arrow_col Axis
#' placement options of inserted arrows. Relative to respective axis ranges.
#'
#' @details
#' The idea behind this function is to add calculated odds ratios of fitted GAM
#' models ([or_gam()]) into a plot showing the smooth function ([plot_gam]) of
#' the chosen predictor for which the odds ratio was calculated for. Multiple
#' insertions can be made by iterative calling the function (see examples).
#'
#' Right now the function only accepts inputs from [or_gam()] objects with
#' `slice = FALSE`. If you want to insert multiple odds ratio values, call the
#' function multiple times.
#'
#' @return [ggplot2]
#' @seealso [plot_gam()], [or_gam()]
#'
#' @examples
#' library(oddsratio)
#' library(mgcv)
#' fit_gam <- gam(y ~ s(x0) + s(I(x1^2)) + s(x2) +
#' offset(x3) + x4, data = data_gam) # fit model
#'
#' # create input objects (plot + odds ratios)
#' plot_object <- plot_gam(fit_gam, pred = "x2", title = "Predictor 'x2'")
#' or_object1 <- or_gam(
#' data = data_gam, model = fit_gam,
#' pred = "x2", values = c(0.099, 0.198)
#' )
#'
#' # insert first odds ratios to plot
#' plot_object <- insert_or(plot_object, or_object1,
#' or_yloc = 3,
#' values_xloc = 0.04, line_size = 0.5,
#' line_type = "dotdash", text_size = 6,
#' values_yloc = 0.5, arrow_col = "red"
#' )
#'
#' # calculate second odds ratio
#' or_object2 <- or_gam(
#' data = data_gam, model = fit_gam, pred = "x2",
#' values = c(0.4, 0.6)
#' )
#'
#' # add or_object2 into plot
#' insert_or(plot_object, or_object2,
#' or_yloc = 2.1, values_yloc = 2,
#' line_col = "green4", text_col = "black",
#' rect_col = "green4", rect_alpha = 0.2,
#' line_alpha = 1, line_type = "dashed",
#' arrow_xloc_r = 0.01, arrow_xloc_l = -0.01,
#' arrow_length = 0.01, rect = TRUE
#' )
#' @export
insert_or <- function(plot_object = NULL,
or_object = NULL,
line_col = "red",
line_size = 1.2,
line_type = "solid",
line_alpha = 1,
text_alpha = 1,
text_size = 4,
text_col = "black",
rect_alpha = 0.5,
rect_col = NULL,
rect = FALSE,
arrow = TRUE,
values = TRUE,
values_yloc = 0,
values_xloc = NULL,
or_yloc = 0,
arrow_length = NULL,
arrow_yloc = NULL,
arrow_col = NULL,
arrow_xloc_r = NULL,
arrow_xloc_l = NULL) {
plot_object <- plot_object +
geom_vline(
xintercept = or_object$value1, color = line_col,
size = line_size, linetype = line_type, alpha = line_alpha
) +
geom_vline(
xintercept = or_object$value2, color = line_col,
size = line_size, linetype = line_type, alpha = line_alpha
) +
annotate("text",
x = mean(c(or_object$value2, or_object$value1)),
y = min(plot_object$data$se_lwr) + or_yloc,
label = paste0("OR: \n", round(or_object$oddsratio, 2)),
color = text_col, size = text_size
)
if (rect) {
if (is.null(rect_col)) {
rect_col <- text_col
}
# set drawing order to place rect behind smoothing fun
plot_object$layers <- c(
geom_rect(
data = plot_object$data[1, ], # avoids multiple rect drawings # nolint
ymin = ggplot_build(plot_object)$layout$panel_params[[1]]$y.range[1],
ymax = ggplot_build(plot_object)$layout$panel_params[[1]]$y.range[2],
xmin = or_object$value1,
xmax = or_object$value2,
alpha = rect_alpha, fill = rect_col
),
plot_object$layers
)
}
if (values) {
if (is.null(values_xloc)) {
# calc x range for x-shift
values_xloc <- 0.03
values_xloc <- (max(plot_object$data$x) - min(plot_object$data$x)) *
values_xloc
}
if (is.null(arrow_length)) {
# calc arrow length from x axis range
arrow_length <- (max(plot_object$data$x) - min(plot_object$data$x)) * 0.01
}
if (is.null(arrow_yloc)) {
# calc arrow height from y axis range
arrow_yloc <- (max(plot_object$data$y) - min(plot_object$data$y)) * 0.05
}
if (is.null(arrow_xloc_l)) {
# calc arrow shift from x axis range
arrow_xloc_l <- -(max(plot_object$data$y) - min(plot_object$data$y)) *
0.002
}
if (is.null(arrow_xloc_r)) {
# calc arrow shift from x axis range
arrow_xloc_r <- (max(plot_object$data$y) - min(plot_object$data$y)) *
0.002
}
plot_object <- plot_object +
annotate("text",
x = or_object$value1 - values_xloc,
y = min(plot_object$data$se_lwr) + values_yloc,
label = or_object$value1,
color = text_col, alpha = text_alpha, size = text_size
) +
annotate("text",
x = or_object$value2 + values_xloc,
y = min(plot_object$data$se_lwr) + values_yloc,
label = or_object$value2,
color = text_col, alpha = text_alpha, size = text_size
)
if (arrow) {
if (is.null(arrow_col)) {
# calc arrow shift from x axis range
arrow_col <- text_col
}
plot_object <- plot_object +
# left arrow
geom_segment(
x = or_object$value1 - values_xloc + arrow_xloc_l,
xend = or_object$value1 - values_xloc + arrow_length,
y = min(plot_object$data$se_lwr) + values_yloc +
arrow_yloc,
yend = min(plot_object$data$se_lwr) + values_yloc +
arrow_yloc,
color = arrow_col,
arrow = arrow(length = unit(0.2, "cm"), type = "closed")
) +
# right arrow
geom_segment(
x = or_object$value2 + values_xloc + arrow_xloc_r,
xend = or_object$value2 + values_xloc - arrow_length,
y = min(plot_object$data$se_lwr) + values_yloc +
arrow_yloc,
yend = min(plot_object$data$se_lwr) + values_yloc +
arrow_yloc,
color = arrow_col,
arrow = arrow(length = unit(0.2, "cm"), type = "closed")
)
}
}
return(plot_object)
}