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

基于HYRIV_ID识别HydroSHEDS河网中目标点的上游河段

基于HydroSHEDS河网数据识别上游河段的实现与优化需求

我采用HydroSHEDS的全球河网数据,该数据集中每个河段拥有唯一的8位编码(HYRIV_ID),本次任务仅依赖NEXT_DOWN字段(存储下游河段的编码)。

为复现目标数据集,我编写了如下代码:

a <- c(41397427, 41397438, 41397439, 41397440, 41397466, 41397467, 41397494, 41397495, 41397512, 41397513, 41397514, 41397566, 41397584)
b <- c(41397438, 41397494, 41397466, 41397439, 41397438, 41397440, 41397401, 41397440, 41397466, 41397439, 41397495, 41397495, 41397494)

# 包含河段ID(HYRIV_ID)和下游河段(NEXT_DOWN)的数据框
df <- data.frame(HYRIV_ID = a, NEXT_DOWN = b)

# 目标点A和B的HYRIV_ID
id <- c(41397494, 41397495)

需要识别上游河段的点A和B

我需要利用向量id中的HYRIV_ID,识别点A和B的所有上游河段。由于实际数据包含更多目标点,我编写了循环遍历id中的所有编码,尝试代码如下:

# 注意:循环可运行,但i=1(点A)的输出不正确,仅识别了第一层上游河段

pt_up <- list() # 创建列表存储每个目标编码的上游HYRIV_ID
for (i in 1:length(id)){
  n <- id[[i]] # 创建存储目标HYRIV_ID及所有上游河段编码的向量
  tmp_id <- df[df$NEXT_DOWN == id[[i]],]$HYRIV_ID # 识别以n为下游的河段

  # 若目标河段为最上游,则无上游河段
  if(length(tmp_id) == 0){
    n <- n
    # 否则,需继续查找上游河段
    }else{
      # 若tmp_id长度大于1,需查找其中每个HYRIV_ID的上游河段
      # 用第二层循环遍历tmp_id中的编码
     for (j in 1:length(tmp_id)){
       tmp_id2 <- df[df$NEXT_DOWN == tmp_id[[j]],]$HYRIV_ID
       if(length(tmp_id2) == 0){
         n <- append(n, tmp_id[[j]]) # 若tmp_id2无上游河段,则将tmp_id中的编码加入n
       }else{
         n <- append(n, tmp_id2) 
       }
     }
    }
  pt_up[[i]] <- n # 将目标河段的上游HYRIV_ID加入列表
  names(pt_up)[i] <- id[[i]] # 为列表元素命名以区分目标河段
  
  }

该代码对B点(i=2)有效,其上游河段均为终点:
点B的上游河段

但对于存在多个分支的A点,需要重复第二层循环以遍历所有新找到的河段。我认为可将第二层循环放入repeat函数中,但不确定具体实现方式:
点A的多分支上游河段

更新

我最终用repeat循环实现了需求,但确信存在更简洁的解决方案!

pt_up <- list() # 创建列表存储每个目标编码的上游HYRIV_ID
for (i in 1:length(id)){
  n <- id[[i]] # 创建存储目标HYRIV_ID及所有上游河段编码的向量
  tmp_id <- df[df$NEXT_DOWN == id[[i]],]$HYRIV_ID # 识别以n为下游的河段
  
  # 若目标河段为最上游,则无上游河段
  if(length(tmp_id) == 0){
    n <- n
    # 否则,需继续查找上游河段
  }else{
    # 若tmp_id长度大于1,需查找其中每个HYRIV_ID的上游河段
    # 用第二层循环遍历tmp_id中的编码
    n <- append(n, tmp_id) # 加入第一层上游河段的HYRIV_ID
    tmp_id2 <- tmp_id # 创建新向量用于循环内更新,避免覆盖原数据
    
    ####### 新增代码段 ######
    repeat{ # 此处添加repeat循环    
      for (j in 1:length(tmp_id2)){ # 遍历tmp_id2中的所有HYRIV_ID,更新后重复执行
      if(length(df[df$NEXT_DOWN == tmp_id2[[j]],]$HYRIV_ID) == 0){
        n <- n # 若tmp_id2无上游河段,保持n不变
      }else{
        id2 <- df[df$NEXT_DOWN == tmp_id2[[j]],]$HYRIV_ID # tmp_id2中编码对应的上游HYRIV_ID
        n <- append(n, id2) # 将编码加入n
      }
      }
      tmp_id2 <- id2 # 更新tmp_id2为新找到的编码,以便重复循环
      if (length(df[df$NEXT_DOWN %in% tmp_id2,]$HYRIV_ID) == 0 & unique(tmp_id2 %in% n) == TRUE){
        break 
      } # 当无剩余上游河段时终止repeat循环
    }
    ####### 新增代码段结束 ######

  pt_up[[i]] <- n # 将目标河段的上游HYRIV_ID加入列表
  names(pt_up)[i] <- id[[i]] # 为列表元素命名以区分目标河段
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 05:01:11