R语言中分割重叠角度区域生成无重叠区域的技术求助
R语言角度区间去重叠分割问题
我用R做数据处理,现有一个包含起始角alpha01、终止角alpha02的数据框,这些角度区间存在重叠。为满足后续计算需求,需要将重叠区域分割为独立的无重叠区间。我尝试过用嵌套循环识别重叠区域并计算重叠值,但在生成新的无重叠起止角时遇到困难。我的思路是:
- 遍历数据框,通过
if(ending_angle1 > starting_angle2 & starting_angle1 < ending_angle2)识别重叠区域,生成标记矩阵 - 计算重叠区域的数值并替换标记
- 尝试生成新的无重叠角度区间,但该步骤受阻,认为可能需要用
while循环反复迭代直到无重叠
以下是我目前的代码及运行结果:
# 数据框结构 baumtabelle_neu <- structure(list( h = c(10, 15, 15, 20), KM = c(8, 10, 10, 13), Nr_Baum = c(1, 2, 3, 4), alpha01 = c(0, 0, 29.5519238759541, 25.9206115365844), alpha02 = c(0, 36.869897645844, 76.7082808323578, 38.0901548795826), e = c(0, 6.32455532033676, 5, 9.4339811320566) ), class = "data.frame", row.names = c(NA, 4L)) # 查看原始数据 baumtabelle_neu #> h KM Nr_Baum alpha01 alpha02 e #> 1 10 8 1 0.00000 0.00000 0.000000 #> 2 15 10 2 0.00000 36.86990 6.324555 #> 3 15 10 3 29.55192 76.70828 5.000000 #> 4 20 13 4 25.92061 38.09015 9.433981 # 计算重叠区域的矩阵 ueberschneidung_wert <- matrix(0, nrow = nrow(baumtabelle_neu), ncol = nrow(baumtabelle_neu)) colnames(ueberschneidung_wert) <- 1:nrow(baumtabelle_neu) for (i in 1:nrow(baumtabelle_neu)) { for (j in 1:nrow(baumtabelle_neu)) { if (i == j){ ueberschneidung_wert[i, j] <- 0 } else if (baumtabelle_neu[i, 5] > baumtabelle_neu[j, 4] & baumtabelle_neu[i, 4] < baumtabelle_neu[j, 5]) { ueberschneidung <- min(baumtabelle_neu[i, 5], baumtabelle_neu[j, 5]) - max(baumtabelle_neu[i, 4], baumtabelle_neu[j, 4]) ueberschneidung_wert[i, j] <- ueberschneidung } else { ueberschneidung_wert[i, j] <- 0 } } } # 尝试生成新的无重叠区间 alpha_raum_neu <- matrix(ncol=3) colnames(alpha_raum_neu) <- c("Nr_Baum", "alpha01_neu", "alpha02_neu") alpha_raum_neu <- as.data.frame(alpha_raum_neu) for (i in 1:nrow(baumtabelle_neu)){ for (j in 1:nrow(baumtabelle_neu)){ if ((ueberschneidung_wert[i, j] > 0) & (baumtabelle_neu[i,4] < baumtabelle_neu[j,4])){ # 非重叠区域(i) alpha_raum_neu[nrow(alpha_raum_neu) + 1,] = list(0) alpha_raum_neu[nrow(alpha_raum_neu), 1] <- paste(baumtabelle_neu[i, 3]) alpha_raum_neu[nrow(alpha_raum_neu), 2] <- baumtabelle_neu[i, 4] alpha_raum_neu[nrow(alpha_raum_neu), 3] <- baumtabelle_neu[i, 5] - ueberschneidung_wert[i,j] # 非重叠区域(j) alpha_raum_neu[nrow(alpha_raum_neu) + 1,] = list(0) alpha_raum_neu[nrow(alpha_raum_neu), 1] <- paste(baumtabelle_neu[j, 3]) alpha_raum_neu[nrow(alpha_raum_neu), 2] <- baumtabelle_neu[j, 4] + ueberschneidung_wert[i,j] alpha_raum_neu[nrow(alpha_raum_neu), 3] <- baumtabelle_neu[j, 5] # 重叠区域(i和j) alpha_raum_neu[nrow(alpha_raum_neu) + 1,] = list(0) alpha_raum_neu[nrow(alpha_raum_neu), 1] <- paste(baumtabelle_neu[i, 3], baumtabelle_neu[j, 3]) alpha_raum_neu[nrow(alpha_raum_neu), 2] <- baumtabelle_neu[j, 4] alpha_raum_neu[nrow(alpha_raum_neu), 3] <- baumtabelle_neu[i, 5] # 移除重复区间 remove_rows <- duplicated(alpha_raum_neu[,2:3], fromLast = TRUE) alpha_raum_neu <- alpha_raum_neu[!remove_rows, ] } } } alpha_raum_neu #> Nr_Baum alpha01_neu alpha02_neu #> 1 <NA> NA NA #> 2 2 0.00000 29.55192 #> 3 3 36.86990 76.70828 #> 4 2 3 29.55192 36.86990 #> 5 2 0.00000 25.92061 #> 6 4 36.86990 38.09015 #> 7 2 4 25.92061 36.86990 #> 8 4 25.92061 29.55192 #> 9 3 38.09015 76.70828 #> 10 4 3 29.55192 38.09015
解决方案:基于断点分割法
无需嵌套循环迭代,更高效的方法是提取所有角度区间的起止点,去重排序后生成无重叠小区间,再匹配对应的原始树木编号:
# 提取所有角度断点,去重并排序 all_breaks <- sort(unique(c(baumtabelle_neu$alpha01, baumtabelle_neu$alpha02))) # 生成无重叠的小区间 new_intervals <- data.frame( alpha01_neu = all_breaks[-length(all_breaks)], alpha02_neu = all_breaks[-1] ) # 过滤长度为0的无效区间 new_intervals <- new_intervals[new_intervals$alpha01_neu != new_intervals$alpha02_neu, ] # 为每个小区间匹配对应的Nr_Baum new_intervals$Nr_Baum <- apply(new_intervals, 1, function(row) { # 找出包含当前区间的原始树木 matches <- which(baumtabelle_neu$alpha01 <= row[1] & baumtabelle_neu$alpha02 >= row[2]) # 拼接编号 paste(baumtabelle_neu$Nr_Baum[matches], collapse = " ") }) # 查看最终结果 new_intervals
运行结果:
alpha01_neu alpha02_neu Nr_Baum 2 0.00000 25.92061 2 3 25.92061 29.55192 2 4 4 29.55192 36.86990 2 3 4 5 36.86990 38.09015 3 4 6 38.09015 76.70828 3
方法说明:
- 提取断点:汇总所有原始区间的起止角,去重排序后得到所有分割边界,这些边界是无重叠区间的基础。
- 生成小区间:相邻断点组成无重叠的小区间,自动避免重叠问题。
- 匹配原始编号:判断每个小区间属于哪些原始树木的区间,拼接编号方便后续关联计算。
内容的提问来源于stack exchange,提问作者sonia
相关产品推荐
相关产品推荐

