Skip to content

Commit 556abf1

Browse files
authored
Refactor analysis functions to utilize cheapr for efficiency (#134)
1 parent f833f90 commit 556abf1

6 files changed

Lines changed: 47 additions & 31 deletions

File tree

DESCRIPTION

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ Imports:
3737
pbmcapply,
3838
rhdf5,
3939
tibble,
40-
tidyr
40+
tidyr,
41+
cheapr (>= 1.5.0)
4142
RoxygenNote: 7.3.3
4243
Roxygen: list(markdown = TRUE)
4344
Suggests:

R/ModelArray_Constructor.R

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ analyseOneElement.lm <- function(i_element,
503503
if (flag_initiate) {
504504
return(list(column_names = NaN, list.terms = NaN))
505505
} else {
506-
onerow <- c(i_element - 1, rep(NaN, (num.stat.output - 1)))
506+
onerow <- c(i_element - 1, cheapr::rep_len_(NaN, num.stat.output - 1L))
507507
return(onerow)
508508
}
509509
}
@@ -545,7 +545,7 @@ analyseOneElement.lm <- function(i_element,
545545
if (flag_initiate) {
546546
return(list(column_names = NaN, list.terms = NaN))
547547
} else {
548-
onerow <- c(i_element - 1, rep(NaN, (num.stat.output - 1)))
548+
onerow <- c(i_element - 1, cheapr::rep_len_(NaN, num.stat.output - 1L))
549549
return(onerow)
550550
}
551551
}
@@ -693,7 +693,7 @@ analyseOneElement.gam <- function(i_element,
693693
sp.criterion.attr.name = NaN
694694
))
695695
} else {
696-
onerow <- c(i_element - 1, rep(NaN, (num.stat.output - 1)))
696+
onerow <- c(i_element - 1, cheapr::rep_len_(NaN, num.stat.output - 1L))
697697
return(onerow)
698698
}
699699
}
@@ -739,7 +739,7 @@ analyseOneElement.gam <- function(i_element,
739739
sp.criterion.attr.name = NaN
740740
))
741741
} else {
742-
onerow <- c(i_element - 1, rep(NaN, (num.stat.output - 1)))
742+
onerow <- c(i_element - 1, cheapr::rep_len_(NaN, num.stat.output - 1L))
743743
return(onerow)
744744
}
745745
}
@@ -976,7 +976,7 @@ analyseOneElement.wrap <- function(i_element,
976976
if (flag_initiate) {
977977
return(list(column_names = NaN))
978978
} else {
979-
onerow <- c(i_element - 1, rep(NaN, (num.stat.output - 1)))
979+
onerow <- c(i_element - 1, cheapr::rep_len_(NaN, num.stat.output - 1L))
980980
return(onerow)
981981
}
982982
}
@@ -1019,7 +1019,7 @@ analyseOneElement.wrap <- function(i_element,
10191019
if (flag_initiate) {
10201020
return(list(column_names = NaN))
10211021
} else {
1022-
onerow <- c(i_element - 1, rep(NaN, (num.stat.output - 1)))
1022+
onerow <- c(i_element - 1, cheapr::rep_len_(NaN, num.stat.output - 1L))
10231023
return(onerow)
10241024
}
10251025
}
@@ -1033,7 +1033,7 @@ analyseOneElement.wrap <- function(i_element,
10331033
if (on_error == "skip" || on_error == "debug") {
10341034
warning(paste0("analyseOneElement.wrap at element ", i_element, ": ", msg))
10351035
if (flag_initiate) return(list(column_names = NaN))
1036-
return(c(i_element - 1, rep(NaN, (num.stat.output - 1))))
1036+
return(c(i_element - 1, cheapr::rep_len_(NaN, num.stat.output - 1L)))
10371037
}
10381038
stop(msg)
10391039
}
@@ -1057,7 +1057,7 @@ analyseOneElement.wrap <- function(i_element,
10571057
if (on_error == "skip" || on_error == "debug") {
10581058
warning(paste0("analyseOneElement.wrap at element ", i_element, ": ", msg))
10591059
if (flag_initiate) return(list(column_names = NaN))
1060-
return(c(i_element - 1, rep(NaN, (num.stat.output - 1))))
1060+
return(c(i_element - 1, cheapr::rep_len_(NaN, num.stat.output - 1L)))
10611061
}
10621062
stop(msg)
10631063
}

R/analyse-helpers.R

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@
426426
response_vals <- scalars(ctx$modelarray)[[ctx$scalar]][i_element, ]
427427

428428
# Start the validity mask with the response scalar
429-
masks <- list(is.finite(response_vals))
429+
valid_mask <- is.finite(response_vals)
430430

431431
# Read and reorder additional attached scalars
432432
scalar_values <- list()
@@ -443,22 +443,25 @@
443443
}
444444

445445
scalar_values[[sname]] <- s_vals
446-
masks[[length(masks) + 1L]] <- is.finite(s_vals)
446+
valid_mask <- valid_mask & is.finite(s_vals)
447447
}
448448

449449
# Intersection mask across all scalars
450-
valid_mask <- Reduce("&", masks)
451-
num_valid <- sum(valid_mask)
450+
which_valid <- cheapr::which_(valid_mask)
451+
num_valid <- length(which_valid)
452452

453453
if (!(num_valid > num.subj.lthr)) {
454454
return(list(dat = NULL, sufficient = FALSE, num_valid = num_valid))
455455
}
456456

457457
# Build filtered data.frame
458-
dat <- ctx$phenotypes[valid_mask, , drop = FALSE]
459-
for (sname in ctx$attached_scalars) {
460-
dat[[sname]] <- scalar_values[[sname]][valid_mask]
461-
}
458+
dat <- cheapr::sset(ctx$phenotypes, which_valid)
459+
scalar_col_list <- lapply(
460+
stats::setNames(ctx$attached_scalars, ctx$attached_scalars),
461+
function(sname) scalar_values[[sname]][which_valid]
462+
)
463+
scalar_cols <- cheapr::fast_df(.args = scalar_col_list)
464+
dat <- cheapr::col_c(dat, scalar_cols)
462465

463466
list(dat = dat, sufficient = TRUE, num_valid = num_valid)
464467
}

R/analyse.R

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,9 @@ ModelArray.lm <- function(formula, data, phenotypes, scalar = NULL, element.subs
149149
...) {
150150
# Validation ----
151151
.validate_modelarray_input(data)
152+
152153
scalar <- .resolve_formula_scalar(formula, data, scalar)
154+
153155
element.subset <- .validate_element_subset(element.subset, data, scalar)
154156
phenotypes <- .align_phenotypes(data, phenotypes, scalar)
155157

@@ -300,9 +302,10 @@ ModelArray.lm <- function(formula, data, phenotypes, scalar = NULL, element.subs
300302
return(invisible(NULL))
301303
}
302304

303-
df_out <- do.call(rbind, fits_all)
304-
df_out <- as.data.frame(df_out)
305-
colnames(df_out) <- column_names
305+
result_mat <- do.call(rbind, fits_all)
306+
col_list <- lapply(seq_len(ncol(result_mat)), function(j) result_mat[, j])
307+
names(col_list) <- column_names
308+
df_out <- cheapr::fast_df(.args = col_list)
306309

307310
df_out <- .correct_pvalues(df_out, list.terms, correct.p.value.terms, var.terms)
308311
df_out <- .correct_pvalues(df_out, "model", correct.p.value.model, var.model)
@@ -474,7 +477,9 @@ ModelArray.gam <- function(formula, data, phenotypes, scalar = NULL, element.sub
474477
...) {
475478
# Validation ----
476479
.validate_modelarray_input(data)
480+
477481
scalar <- .resolve_formula_scalar(formula, data, scalar)
482+
478483
element.subset <- .validate_element_subset(element.subset, data, scalar)
479484
phenotypes <- .align_phenotypes(data, phenotypes, scalar)
480485

@@ -695,9 +700,10 @@ ModelArray.gam <- function(formula, data, phenotypes, scalar = NULL, element.sub
695700
return(invisible(NULL))
696701
}
697702

698-
df_out <- do.call(rbind, fits_all)
699-
df_out <- as.data.frame(df_out)
700-
colnames(df_out) <- column_names
703+
result_mat <- do.call(rbind, fits_all)
704+
col_list <- lapply(seq_len(ncol(result_mat)), function(j) result_mat[, j])
705+
names(col_list) <- column_names
706+
df_out <- cheapr::fast_df(.args = col_list)
701707

702708
# P-value corrections ----
703709
df_out <- .correct_pvalues(df_out, list.smoothTerms, correct.p.value.smoothTerms, var.smoothTerms)
@@ -756,9 +762,13 @@ ModelArray.gam <- function(formula, data, phenotypes, scalar = NULL, element.sub
756762
...
757763
)
758764

759-
reduced.model.df_out <- do.call(rbind, reduced.model.fits)
760-
reduced.model.df_out <- as.data.frame(reduced.model.df_out)
761-
colnames(reduced.model.df_out) <- reduced.model.column_names
765+
result_mat_reduced <- do.call(rbind, reduced.model.fits)
766+
col_list_reduced <- lapply(
767+
seq_len(ncol(result_mat_reduced)),
768+
function(j) result_mat_reduced[, j]
769+
)
770+
names(col_list_reduced) <- reduced.model.column_names
771+
reduced.model.df_out <- cheapr::fast_df(.args = col_list_reduced)
762772

763773
## Compute delta adj R-sq and partial R-sq ----
764774
delta_col <- paste0(changed.rsq.term.shortFormat, ".delta.adj.rsq")
@@ -1104,8 +1114,10 @@ ModelArray.wrap <- function(FUN, data, phenotypes, scalar, element.subset = NULL
11041114
return(invisible(NULL))
11051115
}
11061116

1107-
df_out <- do.call(rbind, fits_all)
1108-
df_out <- as.data.frame(df_out)
1109-
colnames(df_out) <- column_names
1117+
# Better proposed change:
1118+
result_mat <- do.call(rbind, fits_all)
1119+
col_list <- lapply(seq_len(ncol(result_mat)), function(j) result_mat[, j])
1120+
names(col_list) <- column_names
1121+
df_out <- cheapr::fast_df(.args = col_list)
11101122
df_out
11111123
}

man/ModelArray.gam.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/ModelArray.lm.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)