在R语言中合并相同x、y坐标的重复行并计算合并后代表值的技术问询
Alright, let's solve this multi-stemmed tree merging problem you're working on in R. You want to combine rows that share the same x/y coordinates (each row represents a single stem of the same tree) into one row with a representative diameter or cross-sectional area—no simple deduplication, which you already know how to do. Perfect, let's dive in.
Key Background for Forestry Context
First, a quick note on why we don't just average diameters: in forestry, the total cross-sectional area of all stems is a better measure of a tree's overall size than an average diameter. So the standard approach is to sum the cross-sectional areas of each stem at the same location, then calculate an equivalent diameter that represents the total size as if it were a single stem. That said, I'll also show how to swap in custom formulas if you need something else.
Step-by-Step Implementation
We'll use the tidyverse suite since you're already using tibble and ggplot2—it makes grouping and summarizing super straightforward.
1. Load Your Data & Required Package
First, let's confirm we're working with your sample data:
# Load tidyverse (includes tibble, dplyr, ggplot2) library(tidyverse) # Your original data x <- c(6, 6, 6, 2, 2, 3, 4, 4, 7, 8) y <- c(6, 6, 6, 4, 3, 7, 4, 6, 6, 10) diam <- c(12, 9, 7, 16, 19, 4, 7, 8, 9, 3) forest <- tibble(x,y, diam) # Take a quick look at the original data glimpse(forest)
2. Merge Stems by x/y Coordinates
Here's the core code to group by location, calculate merged metrics, and keep one row per tree:
# Merge multi-stemmed trees into single rows forest_merged <- forest %>% # Group all rows that share the same x/y (same tree) group_by(x, y) %>% # Calculate total cross-sectional area (sum of each stem's area) # Area formula for a single stem: π*(diameter/2)² mutate(total_cross_section = sum(pi * (diam / 2)^2)) %>% # Convert total area back to an equivalent single-stem diameter # Formula: sqrt(4*total_area/π) mutate(equivalent_diam = sqrt(4 * total_cross_section / pi)) %>% # Keep only one row per unique tree (we don't need the individual stem rows anymore) slice(1) %>% # Remove grouping to get a regular tibble ungroup() %>% # Optional: Clean up to only keep the columns we care about select(x, y, equivalent_diam, total_cross_section) # Check the merged result forest_merged
3. Visualize to Verify
Let's plot the original individual stems (gray, semi-transparent) against the merged equivalent trees (dark green) to make sure it works:
ggplot() + # Original stems geom_point(data = forest, aes(x = x, y = y, size = diam), color = "gray", alpha = 0.5) + # Merged equivalent trees geom_point(data = forest_merged, aes(x = x, y = y, size = equivalent_diam), color = "darkgreen") + labs(title = "Original Stems vs. Merged Multi-Stemmed Trees", size = "Diameter", caption = "Gray = individual stems | Dark green = merged equivalent") + theme_minimal()
Customizing the Merging Formula
If you need a different representative value instead of the equivalent diameter from cross-sectional area, just swap out the mutate steps. For example:
- Weighted average diameter (weighted by each stem's area):
mutate(weighted_avg_diam = weighted.mean(diam, w = pi*(diam/2)^2)) - Maximum stem diameter (use the largest stem as the representative):
mutate(max_stem_diam = max(diam)) - Simple average diameter (though not recommended for forestry, but just in case):
mutate(simple_avg_diam = mean(diam))
内容的提问来源于stack exchange,提问作者David Cracknell

