如何为abline另一侧的红点寻找最近的等价蓝点?
Hey there! Let's work through this problem of matching each red point to its closest "equivalent" blue point across the y = x line (where an equivalent point would be something like (1,5) matching (5,1)).
First, Let's Clarify the Core Goal
We need to take every red point, map it to its mirror image across the line y = x (swapping x and y coordinates), then find the blue point that's closest to this mirrored position. Your initial approach using coordinate differences and ranking might have fallen short because it likely didn't account for 2D spatial distance—let's fix that.
A Reliable Method for Matching
Instead of just looking at single-axis differences, we'll calculate the Euclidean distance between each red point's mirror and all blue points, then pick the blue point with the smallest distance. Here's how to implement this in R:
Step 1: Load Your Data
First, read in your points data (adjust the path as needed):
red_points <- readRDS("path/to/red_points.rds") blue_points <- readRDS("path/to/blue_points.rds") # Ensure both data frames have columns named `x` and `y` for consistency
Step 2: Find Closest Blue Points
We can use a combination of dplyr and purrr for small-to-medium datasets, or the RANN package for faster nearest-neighbor searches with large datasets:
Option 1: For Small-to-Medium Data
library(dplyr) library(purrr) # Define a helper function to find the closest blue point for a single red point find_closest_blue <- function(red_x, red_y, blue_df) { # Create the mirror point across y=x mirror_x <- red_y mirror_y <- red_x # Calculate distance from mirror to all blue points, then pick the closest blue_df %>% mutate(distance = sqrt((x - mirror_x)^2 + (y - mirror_y)^2)) %>% filter(distance == min(distance)) %>% slice(1) %>% # Handle ties by picking the first match select(blue_x = x, blue_y = y, distance) } # Apply the function to all red points red_points_with_matches <- red_points %>% mutate(closest_blue = pmap(list(x, y), find_closest_blue, blue_df = blue_points)) %>% unnest_wider(closest_blue)
Option 2: For Large Data (Faster)
Use the nn2 function from RANN to do optimized nearest-neighbor searches:
library(RANN) library(dplyr) # Convert points to matrices for the nearest-neighbor function blue_coords <- as.matrix(blue_points[, c("x", "y")]) red_mirror_coords <- as.matrix(red_points[, c("y", "x")]) # Swap x/y for mirror # Find the closest blue point to each red mirror nn_results <- nn2(blue_coords, red_mirror_coords, k = 1) # Attach results to red points data frame red_points_with_matches <- red_points %>% mutate( blue_x = blue_points$x[nn_results$nn.idx], blue_y = blue_points$y[nn_results$nn.idx], distance = nn_results$nn.dists )
Verifying with ggplot (Your Suspected Solution)
Your ggplot code is a great way to visualize whether the matches are correct! If your code looks something like this, it absolutely aligns with the expected outcome:
library(ggplot2) ggplot() + # Plot all blue points geom_point(data = blue_points, aes(x, y), color = "blue", size = 2) + # Plot all red points geom_point(data = red_points_with_matches, aes(x, y), color = "red", size = 2) + # Draw lines connecting red points to their matched blue points geom_segment( data = red_points_with_matches, aes(x = x, y = y, xend = blue_x, yend = blue_y), color = "gray50", linetype = "dashed" ) + # Add the y=x reference line geom_abline(intercept = 0, slope = 1, color = "black", linewidth = 1) + theme_minimal() + labs(title = "Red Points Matched to Closest Equivalent Blue Points (y=x Axis)", x = "X Coordinate", y = "Y Coordinate")
This plot will let you visually confirm:
- Lines between red and blue points are roughly symmetric across
y=x - Closest matches are indeed the nearest blue points to each red's mirror position
Why This Works Better Than Your Initial Approach
Your earlier method using coordinate differences and ranking might have only looked at x or y differences in isolation. By calculating the Euclidean distance from the mirrored red point to blue points, we're considering the full 2D space—this ensures we pick the truly closest point, not just the closest along one axis.
内容的提问来源于stack exchange,提问作者crysis405

