@@ -2,6 +2,14 @@ library(magrittr)
2
2
library(shiny )
3
3
library(dbplyr )
4
4
5
+ # ' Reads a ulog file and outputs a tibble
6
+ # '
7
+ # ' @param path Filepath to the ulog file
8
+ # '
9
+ # ' @return A tibble
10
+ # ' @export
11
+ # '
12
+ # ' @examples
5
13
ulog_to_df = function (path ){
6
14
con = DBI :: dbConnect(RSQLite :: SQLite(), dbname = path )
7
15
dplyr :: inner_join(
@@ -17,8 +25,17 @@ ulog_to_df = function(path){
17
25
dplyr :: relocate(id , time , conc )
18
26
}
19
27
20
- segment = function (df , minseglen ){
21
- cpt_model = EnvCpt :: envcpt(df $ conc , models = " trendcpt" , minseglen = minseglen )$ trendcpt
28
+ # ' Segments a respirometry data frame
29
+ # '
30
+ # ' @param df Containing a "conc" column, which contains the concentration
31
+ # ' @param ... Extra parameters to pass into `envcpt`
32
+ # '
33
+ # ' @return
34
+ # ' @export
35
+ # '
36
+ # ' @examples
37
+ segment = function (df , ... ){
38
+ cpt_model = EnvCpt :: envcpt(df $ conc , models = " trendcpt" , ... )$ trendcpt
22
39
purrr :: pmap_dfr(list (
23
40
seq_along(cpt_model @ cpts ),
24
41
dplyr :: lag(cpt_model @ cpts , default = 0 ),
@@ -42,7 +59,17 @@ vline = function(x = 0, ...) {
42
59
)
43
60
}
44
61
45
- make_plot = function (df , segments , selected_segment ){
62
+ # ' Make the interactive plotly plot for showing the entire time series of a single logger run
63
+ # '
64
+ # ' @param df The data frame for a single logger run, containing `time`, and `conc` columns
65
+ # ' @param segments A data frame containing segments, containing `time`, and `fitted` columns
66
+ # ' @param selected_segment A data frame containing one or more selected rows. This has the same format as, and should be a subset of the `segments` argument.
67
+ # '
68
+ # ' @return The plotly object
69
+ # ' @export
70
+ # '
71
+ # ' @examples
72
+ make_macro_plot = function (df , segments , selected_segment ){
46
73
plotly :: plot_ly() %> %
47
74
plotly :: add_trace(name = " Data" , data = df , x = ~ time , y = ~ conc , type = ' scatter' , mode = ' markers' ) %> %
48
75
plotly :: add_trace(name = " Fit" , data = segments , x = ~ time , y = ~ fitted , type = ' scatter' , mode = ' lines' , line = list (color = ' orange' , width = 2 )) %> %
@@ -57,28 +84,41 @@ make_plot = function(df, segments, selected_segment){
57
84
}
58
85
59
86
# Define server logic required to draw a histogram
60
- shiny :: shinyServer(function (input , output ) {
87
+ shiny :: shinyServer(function (input , output , session ) {
61
88
62
- df = reactive({
89
+ all_loggers = reactive({
63
90
if (input $ files %> % length == 0 ){ return (NULL ) }
64
91
input $ files $ datapath %> %
65
92
dplyr :: first() %> %
66
- ulog_to_df() %> %
67
- dplyr :: filter(logger == paste(" Logger" , input $ logger ))
93
+ ulog_to_df()
68
94
})
69
95
70
- segments = reactive ({
96
+ observe ({
71
97
if (input $ files %> % length == 0 ){ return (NULL ) }
98
+ updateSelectInput(session = session , inputId = ' logger' , choices = all_loggers() %> % dplyr :: pull(logger ))
99
+ })
100
+
101
+ ready_to_plot = reactive({
102
+ input $ files %> % length > 0 && input $ logger != " "
103
+ })
104
+
105
+ df = reactive({
106
+ if (! ready_to_plot()){ return (NULL ) }
107
+ all_loggers() %> % dplyr :: filter(logger == input $ logger )
108
+ })
109
+
110
+ segments = reactive({
111
+ if (! ready_to_plot()){ return (NULL ) }
72
112
segment(df(), input $ minseglen )
73
113
})
74
114
75
115
output $ segments = plotly :: renderPlotly({
76
- if (input $ files % > % length == 0 ){ return (NULL ) }
77
- make_plot (df(), segments(), selected_segment()) %> % plotly :: event_register(" plotly_click" )
116
+ if (! ready_to_plot() ){ return (NULL ) }
117
+ make_macro_plot (df(), segments(), selected_segment()) %> % plotly :: event_register(" plotly_click" )
78
118
})
79
119
80
120
selected_point = reactive({
81
- if (input $ files % > % length == 0 ){ return (NULL ) }
121
+ if (! ready_to_plot() ){ return (NULL ) }
82
122
83
123
# This returns the single row of data corresponding to where the user clicked
84
124
d = plotly :: event_data(" plotly_click" )
@@ -88,10 +128,12 @@ shiny::shinyServer(function(input, output) {
88
128
89
129
x = d $ x [[1 ]]
90
130
segment = segments()
91
- segment %> % dplyr :: filter(dplyr :: near(time , x , tol = 0.5 ))
131
+ segment %> % dplyr :: filter(dplyr :: near(time , x , tol = 0.05 ))
92
132
})
93
133
94
134
selected_segment = reactive({
135
+ if (! ready_to_plot()){ return (NULL ) }
136
+
95
137
# This returns all the rows corresponding to all the data points in the current model segment
96
138
sel = selected_point()
97
139
all_seg = segments()
@@ -102,25 +144,34 @@ shiny::shinyServer(function(input, output) {
102
144
all_seg %> % dplyr :: filter(model_number == sel $ model_number )
103
145
})
104
146
105
- output $ description = renderPrint({
147
+ output $ description = renderTable({
148
+ region = selected_segment()
106
149
segment = selected_point()
107
- if (is.null(segment ) || nrow(segment ) == 0 ){ return (NULL ) }
108
-
150
+ if (is.null(segment ) || nrow(segment ) == 0 || nrow(region ) == 0 ){ return (NULL ) }
109
151
lm = segment %> % dplyr :: pull(lm ) %> % dplyr :: first()
110
152
cofs = coefficients(lm )
111
- equation = stringr :: str_glue(
112
- " f(x) = {slope}x + {intercept}" ,
113
- slope = formatC(cofs [[2 ]], digits = 3 ),
114
- intercept = formatC(cofs [[1 ]], digits = 3 )
115
- )
116
- rsquared = (lm %> % vcov() %> % cov2cor() %> % `[[`(1 , 2 ))^ 2
117
- stringr :: str_glue(" {equation}\n R Squared: {r2}" , equation = equation , r2 = rsquared %> % formatC(digits = 3 ))
118
- })
153
+
154
+ list (
155
+ c(' Equation' , stringr :: str_glue(
156
+ " f(x) = {slope}x + {intercept}" ,
157
+ slope = formatC(cofs [[2 ]], digits = 3 ),
158
+ intercept = formatC(cofs [[1 ]], digits = 3 )
159
+ ) %> % as.character ),
160
+ c(' R Squared' , lm %> % summary %> % `$`(' r.squared' ) %> % as.character ),
161
+ c(' Intercept (μ mol L<sup>-1</sup>)' , cofs %> % `[[`(1 ) %> % as.character ),
162
+ c(' Rate (μ mol L <sup>-1</sup> s<sup>-1</sup>)' , cofs %> % `[[`(2 ) %> % as.character ),
163
+ c(' Rate (μ mol L <sup>-1</sup> min<sup>-1</sup>)' , cofs %> % `[[`(2 ) %> % `*`(60 ) %> % as.character ),
164
+ c(' Segment Start (sec)' , region $ time %> % min %> % as.character ),
165
+ c(' Segment End (sec)' , region $ time %> % max %> % as.character )
166
+ ) %> % purrr :: map_dfr(function (l ){
167
+ tibble :: tibble_row(Attribute = l [[1 ]], Value = l [[2 ]])
168
+ })
169
+ }, sanitize.text.function = function (x ) x , striped = TRUE , width = " 100%" , colnames = FALSE )
119
170
120
171
output $ fit = renderPlot({
121
172
segment = selected_point()
122
173
if (is.null(segment ) || nrow(segment ) == 0 ){ return (NULL ) }
123
-
174
+
124
175
lm = segment %> % dplyr :: pull(lm ) %> % dplyr :: first()
125
176
cofs = coefficients(lm )
126
177
ggplot2 :: ggplot(lm $ model , ggplot2 :: aes(x = time , y = conc )) +
0 commit comments