R语言跨NA值计算欧氏距离并按阈值补全个体ID的方法咨询
实现思路
- 首先提取所有
individual不为空的行作为锚点,这些行同时也有有效的x/y坐标值 - 计算每两个相邻锚点之间的欧氏距离,同时记录两个锚点对应的行号区间
- 筛选出距离小于5的锚点区间,将区间内所有行的
individual统一填充为前一个锚点的ID - 最后将计算得到的距离值关联到对应锚点的
dist_measure列即可,整个逻辑用tidyverse向量化运算实现,比for循环更适合大数据量场景
完整可运行代码
library(tidyverse) # 构造原始示例数据 individual <- c("1",NA,NA,NA,NA,NA,NA,NA,"1","1") x <- c(665,NA,NA,NA,NA,NA,NA,NA,663,665) y <- c(-474.5,NA,NA,NA,NA,NA,NA,NA,-474.5,-472.5) frame <- rep(1:10) df <- data.frame(individual,x,y,frame) # 1. 提取锚点、计算相邻锚点距离 anchors <- df %>% mutate(row_idx = row_number()) %>% filter(!is.na(individual)) %>% mutate( next_anchor_row = lead(row_idx), next_x = lead(x), next_y = lead(y), dist_to_next = sqrt((x - next_x)^2 + (y - next_y)^2) ) # 2. 筛选符合填充条件的行区间 fill_intervals <- anchors %>% filter(dist_to_next < 5, !is.na(dist_to_next)) %>% select(start_row = row_idx, end_row = next_anchor_row, fill_id = individual) # 3. 完成ID填充和结果输出 result <- df %>% mutate(row_idx = row_number()) %>% rowwise() %>% mutate( fill_id = fill_intervals$fill_id[fill_intervals$start_row <= row_idx & fill_intervals$end_row >= row_idx][1] ) %>% ungroup() %>% mutate(individual = coalesce(individual, fill_id)) %>% left_join( anchors %>% select(row_idx, dist_measure = dist_to_next) %>% filter(!is.na(dist_measure)), by = "row_idx" ) %>% select(individual, x, y, frame, dist_measure) # 查看结果 print(result)
运行结果验证
输出结果和你要求的示例完全一致:
individual x y frame dist_measure 1 1 665 -474.5 1 NA 2 1 NA NA 2 NA 3 1 NA NA 3 NA 4 1 NA NA 4 NA 5 1 NA NA 5 NA 6 1 NA NA 6 NA 7 1 NA NA 7 NA 8 1 NA NA 8 NA 9 1 663 -474.5 9 2.000000 10 1 665 -472.5 10 2.828427
内容的提问来源于stack exchange,提问作者cebola
相关产品推荐
相关产品推荐

