如何用lapply同时遍历两个列表应用函数?多因子数据统计分析求助
Hey there! Let's break down how to iterate over two lists simultaneously to apply your movThreshold function, along with fitting it to your specific workflow of subsetting by uniqueGroup and running Wilcoxon tests.
First, Clarify Your Use Case
Before jumping into code, let's align on two common scenarios you might be dealing with:
- Paired iteration: You have two lists of the same length, where each element in the first list pairs with the corresponding element in the second (e.g., threshold 1 goes with group subset 1, threshold 2 with group subset 2, etc.)
- All combinations: You want to apply every threshold in
th.listto every subset created byuniqueGroup(i.e., every threshold-group pair)
Scenario 1: Paired Iteration (One-to-One Matching)
If you're pairing elements from two lists, base R's Map() is your go-to replacement for lapply (it's designed for multi-list iteration). Alternatively, if you use the tidyverse, purrr::map2() is more readable.
Base R with Map()
Let's say you have your threshold list th.list, and a list of data subsets split by uniqueGroup called group_subsets (created with group_subsets <- split(tab, tab$uniqueGroup)). You can pass both lists to Map, along with any fixed parameters like dependent = "infGrad":
# First, split your data by uniqueGroup group_subsets <- split(tab, tab$uniqueGroup) # Use Map to pair thresholds with subsets paired_results <- Map( f = function(threshold, subset_data) { movThreshold(threshold = threshold, tab = subset_data, dependent = "infGrad") }, threshold = th.list, subset_data = group_subsets )
Or, if your movThreshold function's parameter order matches the order of your lists, you can simplify it with MoreArgs for fixed parameters:
paired_results <- Map( movThreshold, th.list, group_subsets, MoreArgs = list(dependent = "infGrad") )
Tidyverse with purrr::map2()
If you prefer the tidyverse syntax, map2() makes the pairing explicit:
library(purrr) group_subsets <- split(tab, tab$uniqueGroup) paired_results <- map2( .x = th.list, # First list: thresholds .y = group_subsets, # Second list: group subsets .f = ~ movThreshold(threshold = .x, tab = .y, dependent = "infGrad") )
Scenario 2: All Threshold-Group Combinations
If you want to test every threshold against every uniqueGroup subset, you'll first generate all possible pairs, then iterate over those pairs.
Base R with expand.grid + lapply
First, create a data frame of all combinations, then loop through each row:
group_subsets <- split(tab, tab$uniqueGroup) # Generate all threshold-group pairs all_combos <- expand.grid( threshold = th.list, subset_data = group_subsets, stringsAsFactors = FALSE ) # Iterate over each combination combo_results <- lapply(1:nrow(all_combos), function(i) { movThreshold( threshold = all_combos$threshold[[i]], tab = all_combos$subset_data[[i]], dependent = "infGrad" ) })
Tidyverse with purrr::pmap()
pmap() is perfect for iterating over rows of a data frame (or list of lists) with multiple parameters:
library(purrr) group_subsets <- split(tab, tab$uniqueGroup) all_combos <- expand.grid(threshold = th.list, subset_data = group_subsets, stringsAsFactors = FALSE) combo_results <- pmap(all_combos, movThreshold, dependent = "infGrad")
Can You Do This with lapply Alone?
Technically yes, but it's less clean. You'd need to "pack" your two lists into a single list where each element is a pair of corresponding values, then unpack them inside the lapply function:
# Pack the two lists into one list of pairs packed_pairs <- mapply(list, th.list, group_subsets, SIMPLIFY = FALSE) # Iterate with lapply lapply_results <- lapply(packed_pairs, function(pair) { movThreshold(threshold = pair[[1]], tab = pair[[2]], dependent = "infGrad") })
But this is just a workaround—Map or map2 are far more intuitive for this job.
内容的提问来源于stack exchange,提问作者maycca

