Last active
July 31, 2025 10:22
-
-
Save jrosell/49917cbfd4b1e7e29591af9ec35d6713 to your computer and use it in GitHub Desktop.
lapply and unlist are common base R operations chained together. That's the typical flatmap operation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Refrence: https://www.biobits.be/biofunctor/2025/07/30/what-s-r-vector-victor/ | |
# Laboratory experiments are often performed in 96-well plastic plates, with 8 rows (labeled A-H) and 12 columns (labeled 1-12). Each microwell is a separate micro-experiment (labeled A1-H12). | |
rows <- LETTERS[1:8] | |
columns <- 1:12 |> sprintf(fmt = "%02i") | |
# Recycled vectors is not what we want here. | |
paste0(rows, columns) | |
#> [1] "A01" "B02" "C03" "D04" "E05" "F06" "G07" "H08" "A09" "B10" "C11" "D12" | |
paste01 <- \(x, y) { stopifnot(length(x) == 1L); paste0(x, y)} | |
flatmap <- function(X, FUN, ..., USE.NAMES = TRUE) { | |
unlist(lapply(X, FUN, ...), recursive = FALSE, use.names = USE.NAMES) | |
} | |
map_vec <- function(X, FUN, ...) { | |
Vectorize(function(x) FUN(x, ...))(X) |> | |
as.vector() | |
} | |
results <- bench::mark( | |
expand_grid = { | |
grid <- expand.grid(Column = columns, Row = rows) | |
expand_grid_res <- paste0(grid$Row, grid$Column) | |
expand_grid_res | |
}, | |
rep = { | |
rows_rep <- rep(rows, each = length(columns)) | |
columns_rep <- rep(columns, times = length(rows)) | |
rep_res <- paste0(rows_rep, columns_rep) | |
rep_res | |
}, | |
paste01_lapply_unlist = { | |
paste01_lapply_unlist_res <- rows |> | |
lapply(paste01, columns) |> | |
unlist(recursive = FALSE) | |
paste01_lapply_unlist_res | |
}, | |
flatmap_paste01 = { | |
flatmap_paste01_res <- flatmap(rows, paste01, columns) | |
flatmap_paste01_res | |
}, | |
flatmap_paste0 = { | |
flatmap_paste0_res <- flatmap(rows, paste0, columns) | |
flatmap_paste0_res | |
}, | |
vectorize_paste0 = { | |
vectorize_paste0_res <- | |
Vectorize(\(x) paste0(x, columns))(rows) |> as.vector() | |
vectorize_paste0_res | |
}, | |
vectorize_paste01 = { | |
vectorize_paste01_res <- | |
Vectorize(\(x) paste01(x, columns))(rows) |> as.vector() | |
vectorize_paste01_res | |
}, | |
map_vec_paste0 = { | |
map_vec_paste0_res <- | |
rows |> map_vec(paste0, columns) | |
map_vec_paste0_res | |
}, | |
map_vec_paste01 = { | |
map_vec_paste01_res <- | |
rows |> map_vec(paste01, columns) | |
map_vec_paste01_res | |
} | |
) | |
results[,c("expression", "median", "mem_alloc")] | |
#> # A tibble: 9 × 3 | |
#> expression median mem_alloc | |
#> <bch:expr> <bch:tm> <bch:byt> | |
#> 1 expand_grid 43.1µs 63.59KB | |
#> 2 rep 10.3µs 2.39KB | |
#> 3 paste01_lapply_unlist 31.1µs 4.01MB | |
#> 4 flatmap_paste01 31.3µs 816B | |
#> 5 flatmap_paste0 18µs 23.41KB | |
#> 6 vectorize_paste0 55.4µs 71.24KB | |
#> 7 vectorize_paste01 68.7µs 7.34KB | |
#> 8 map_vec_paste0 55µs 2.39KB | |
#> 9 map_vec_paste01 69.5µs 35.95KB | |
rep_res | |
#> [1] "A01" "A02" "A03" "A04" "A05" "A06" "A07" "A08" "A09" "A10" "A11" "A12" | |
#> [13] "B01" "B02" "B03" "B04" "B05" "B06" "B07" "B08" "B09" "B10" "B11" "B12" | |
#> [25] "C01" "C02" "C03" "C04" "C05" "C06" "C07" "C08" "C09" "C10" "C11" "C12" | |
#> [37] "D01" "D02" "D03" "D04" "D05" "D06" "D07" "D08" "D09" "D10" "D11" "D12" | |
#> [49] "E01" "E02" "E03" "E04" "E05" "E06" "E07" "E08" "E09" "E10" "E11" "E12" | |
#> [61] "F01" "F02" "F03" "F04" "F05" "F06" "F07" "F08" "F09" "F10" "F11" "F12" | |
#> [73] "G01" "G02" "G03" "G04" "G05" "G06" "G07" "G08" "G09" "G10" "G11" "G12" | |
#> [85] "H01" "H02" "H03" "H04" "H05" "H06" "H07" "H08" "H09" "H10" "H11" "H12" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment