You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

方法说明:

  1. 提取断点:汇总所有原始区间的起止角,去重排序后得到所有分割边界,这些边界是无重叠区间的基础。
  2. 生成小区间:相邻断点组成无重叠的小区间,自动避免重叠问题。
  3. 匹配原始编号:判断每个小区间属于哪些原始树木的区间,拼接编号方便后续关联计算。

内容的提问来源于stack exchange,提问作者sonia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 12:37:04