@@ -78,23 +78,22 @@ read_keyvalue <- function(drfile, sheet, ranges, translate = FALSE, translations
7878# ' @noRd
7979# '
8080read_table <- function (drfile , sheet , ranges , translate = FALSE , translations = NULL , atomicclass = " character" , ... ) {
81+ # Read and combine data from the specified ranges
8182 tbl <- lapply(ranges , function (range ) {
82- readxl :: read_excel(drfile , sheet = sheet , range = range )}) | >
83- dplyr :: bind_rows()
83+ readxl :: read_excel(drfile , sheet = sheet , range = range )
84+ }) | > dplyr :: bind_rows()
8485
86+ # Coerce columns to the specified atomic class
8587 if (length(atomicclass ) == 1 ) {
86- for (i in seq_along(tbl )) {
87- tbl [[i ]] <- tbl [[i ]] | > coerce(atomicclass )
88- }
88+ tbl [] <- lapply(tbl , coerce , atomicclass )
8989 } else {
90- if (! length(atomicclass ) = = ncol(tbl )) {
90+ if (length(atomicclass ) ! = ncol(tbl )) {
9191 rlang :: abort(" The number of atomic classes must be 1 or equal to the number of columns in the table." )
9292 }
93- for (i in seq_along(atomicclass )) {
94- tbl [[i ]] <- tbl [[i ]] | > coerce(atomicclass [i ])
95- }
93+ tbl [] <- Map(coerce , tbl , atomicclass )
9694 }
9795
96+ # Translate column names if required
9897 if (translate ) {
9998 names(tbl ) <- long_to_shortnames(names(tbl ), translations )
10099 }
@@ -187,80 +186,121 @@ short_to_longnames <- function(v, translations) {
187186# ' @export
188187# '
189188read_data <- function (drfile , guide , checkname = FALSE ) {
190-
189+ # Load the guide if it's a file path
191190 if (inherits(guide , " character" )) {
192- # If 'guide' is a file path then read the guide
193191 guide <- read_guide(guide )
194- } else {
195- if (! inherits(guide , " guide" )) {
196- cl <- class(guide )
197- rlang :: abort(glue :: glue(" The guide must be a path (character) to a guide file or a reporting template guide object (guide object), not an object of class {cl}." ))
198- }
192+ } else if (! inherits(guide , " guide" )) {
193+ rlang :: abort(glue :: glue(
194+ " The guide must be a path (character) to a guide file or a reporting template guide object (guide object), not an object of class {class(guide)}."
195+ ))
199196 }
200197
201198 result <- list ()
202199
200+ # Process each location in the guide
203201 for (location in guide $ locations ) {
204202 read_function <- switch (
205203 location $ type ,
206204 " keyvalue" = read_keyvalue ,
207205 " table" = read_table ,
208- " platedata" = read_key_plate
206+ " platedata" = read_key_plate ,
207+ " cells" = read_cells ,
208+ rlang :: abort(glue :: glue(" Unsupported location type: {location$type}" ))
209209 )
210210
211- atomicclass <- if (" atomicclass" %in% names(location )) location $ atomicclass else " character"
212-
213- if (! location $ type == " cells" ) {
214- chunk <- read_function(drfile = drfile , sheet = location $ sheet , ranges = location $ ranges ,
215- translate = location $ translate , translations = guide $ translations ,
216- atomicclass = atomicclass )
217- } else {
218- chunk <- read_cells(drfile = drfile , sheet = location $ sheet , variables = location $ variables , translate = location $ translate ,
219- translations = guide $ translations , atomicclass = atomicclass )
220- }
211+ atomicclass <- location $ atomicclass %|| % " character"
221212
222- if (! (location $ varname %in% names(result [[location $ type ]]))) {
223- result [[location $ type ]][[location $ varname ]] <- chunk
213+ # Read data using the appropriate function
214+ chunk <- if (location $ type == " cells" ) {
215+ read_function(
216+ drfile = drfile ,
217+ sheet = location $ sheet ,
218+ variables = location $ variables ,
219+ translate = location $ translate ,
220+ translations = guide $ translations ,
221+ atomicclass = atomicclass
222+ )
224223 } else {
225- result [[location $ type ]][[location $ varname ]] <- switch (
226- location $ type ,
227- " keyvalue" = c(result [[location $ type ]][[location $ varname ]], chunk ),
228- " table" = dplyr :: bind_rows(result [[location $ type ]][[location $ varname ]], chunk ),
229- " platedata" = suppressMessages(dplyr :: full_join(result [[location $ type ]][[location $ varname ]], chunk )),
230- " cells" = c(result [[location $ type ]][[location $ varname ]], chunk ),
224+ read_function(
225+ drfile = drfile ,
226+ sheet = location $ sheet ,
227+ ranges = location $ ranges ,
228+ translate = location $ translate ,
229+ translations = guide $ translations ,
230+ atomicclass = atomicclass
231231 )
232232 }
233+
234+ # Combine results
235+ result [[location $ type ]][[location $ varname ]] <- combine_results(
236+ result [[location $ type ]][[location $ varname ]],
237+ chunk ,
238+ location $ type
239+ )
233240 }
234241
235- template.version <- result $ cells $ .template $ version
236- if (grepl(" ^\\ d+$" , template.version )) {
237- template.version <- paste0(template.version , " .0" )
238- rlang :: warn(glue :: glue(" Incorrectly formatted template version number '{result$cells$.template$version}'. Version
239- numbers must have a minor number. Will interpret '{result$cells$.template$version}' as '{template.version}'." ))
242+ # Validate template version
243+ validate_template_version(result $ cells $ .template $ version , guide )
244+
245+ # Check template name if required
246+ if (checkname && guide $ template.name != result $ template.metadata $ template.name ) {
247+ rlang :: abort(glue :: glue(
248+ " The name of the guide ({guide$template.name}) does not match the name of the excel template ({result$template.metadata$template.name})."
249+ ))
240250 }
241- num.template.version <- package_version(template.version )
242- num.min.version <- package_version(guide $ template.min.version )
243251
244- if (num.template.version < num.min.version ) {
245- rlang :: abort(glue :: glue(" The guide is incompatible with the template.
246- The template version should be minimally {guide$template.min.version}, whereas it is {result$template.metadata$template.version}." ))
252+ result $ .sourcefile <- drfile
253+ result $ .guide <- guide
254+ result
255+ }
256+
257+ # ' Helper function to combine results based on location type
258+ # ' @param existing The existing data
259+ # ' @param chunk The new data
260+ # ' @param type The location type
261+ # ' @noRd
262+ combine_results <- function (existing , chunk , type ) {
263+ if (is.null(existing )) {
264+ return (chunk )
247265 }
248266
249- if (! is.null(guide $ template.max.version )) {
250- num.max.version <- package_version(guide $ template.max.version )
251- if (num.max.version < num.template.version ) {
252- rlang :: abort(glue :: glue(" The guide is incompatible with the template.
253- The template version should be maximally {guide$template.max.version}, whereas it is {result$template.metadata$template.version}." ))
254- }
267+ switch (
268+ type ,
269+ " keyvalue" = c(existing , chunk ),
270+ " table" = dplyr :: bind_rows(existing , chunk ),
271+ " platedata" = suppressMessages(dplyr :: full_join(existing , chunk )),
272+ " cells" = c(existing , chunk ),
273+ rlang :: abort(glue :: glue(" Unsupported location type for combining results: {type}" ))
274+ )
275+ }
276+
277+ # ' Helper function to validate template
278+ # ' @param template_version The version of the template
279+ # ' @param guide The guide object
280+ # ' @noRd
281+ validate_template_version <- function (template_version , guide ) {
282+ if (grepl(" ^\\ d+$" , template_version )) {
283+ template_version <- paste0(template_version , " .0" )
284+ rlang :: warn(glue :: glue(
285+ " Incorrectly formatted template version number '{template_version}'. Version numbers must have a minor number. Interpreting as '{template_version}'."
286+ ))
255287 }
256288
257- if (checkname ) {
258- if (guide $ template.name != result $ template.metadata $ template.name ) {
259- rlang :: abort(glue :: glue(" The name of the guide ({guide$template.name}) does not match the name of the excel template ({result$template.metadata$template.name})." ))
260- }
289+ num_template_version <- package_version(template_version )
290+ num_min_version <- package_version(guide $ template.min.version )
291+
292+ if (num_template_version < num_min_version ) {
293+ rlang :: abort(glue :: glue(
294+ " The guide is incompatible with the template. The template version should be at least {guide$template.min.version}, but it is {template_version}."
295+ ))
261296 }
262297
263- result $ .sourcefile <- drfile
264- result $ .guide <- guide
265- result
298+ if (! is.null(guide $ template.max.version )) {
299+ num_max_version <- package_version(guide $ template.max.version )
300+ if (num_template_version > num_max_version ) {
301+ rlang :: abort(glue :: glue(
302+ " The guide is incompatible with the template. The template version should be at most {guide$template.max.version}, but it is {template_version}."
303+ ))
304+ }
305+ }
266306}
0 commit comments