R语言:多层嵌套列表中按层级统计1/2出现次数并求和
First, let's break down the problem into manageable steps:
- Count 1s and 2s in a single data frame: Create a helper function that takes a data frame and returns the total number of entries that are either 1 or 2.
- Sum counts per year: For each year (the middle level of your nested list), apply the helper function to all data frames in that year and sum the results.
- Preserve the species-year hierarchy: Use nested iteration to keep the structure of your original list while computing the sums.
Base R Implementation
First, define the helper function to handle individual data frames:
# Helper function to count occurrences of 1 or 2 in a data frame count_12 <- function(df) { sum(df %in% c(1, 2)) }
Next, use nested lapply() calls to process the nested list structure:
# Calculate total counts per year, grouped by species yearly_sums <- lapply(ll, function(species_data) { lapply(species_data, function(year_data) { # Get counts for each data frame in the year, then sum them df_counts <- sapply(year_data, count_12) sum(df_counts) }) })
Testing with Your Example
Let's verify this works with your sample data. With set.seed(42):
l1contains[1, 0, 0, 0, 0], socount_12(l1) = 1l2contains[2, 2, 2, 1, 0], socount_12(l2) = 4
Each year (e.g., ll[[1]][[1]]) is a list of l1 and l2, so the sum is 1 + 4 = 5. Running the code above will return:
yearly_sums # [[1]] # [[1]][[1]] # [1] 5 # # [[1]][[2]] # [1] 5 # # [[2]] # [[2]][[1]] # [1] 5 # # [[2]][[2]] # [1] 5
Adding Readable Names (Optional)
To make the output easier to interpret, you can add descriptive names to the result:
# Name species and year levels names(yearly_sums) <- paste0("Species_", 1:length(yearly_sums)) for (i in seq_along(yearly_sums)) { names(yearly_sums[[i]]) <- paste0("Year_", 1:length(yearly_sums[[i]])) } # View the named result yearly_sums # $Species_1 # $Species_1$Year_1 # [1] 5 # # $Species_1$Year_2 # [1] 5 # # $Species_2 # $Species_2$Year_1 # [1] 5 # # $Species_2$Year_2 # [1] 5
Alternative Using purrr (For Tidyverse Users)
If you prefer the tidyverse ecosystem, you can use purrr functions for a more pipe-friendly syntax:
library(purrr) # Function to sum counts for all data frames in a year sum_year_counts <- function(year_data) { year_data %>% map_dbl(count_12) %>% sum() } # Compute results with nested map calls yearly_sums_purrr <- ll %>% map(map, sum_year_counts)
This will produce the same result as the base R version but with a more concise, readable structure for users familiar with tidyverse tools.
内容的提问来源于stack exchange,提问作者Simon

