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

R语言中计算环形布置陷阱的中位步距问题求助

环形陷阱中位距离计算问题解决

问题背景

需要按池塘和年份分组,计算捕获小龙虾的环形布置陷阱之间的中位距离。陷阱沿池塘岸线环形排列,距离取最短路径(比如10个陷阱的池塘中,陷阱1和9的距离为2而非8),且不计算同一陷阱间的距离。

示例数据集构建代码

# Create vectors for each column
Pond <- c("Aubrees", "Aubrees", "Kohls", "Kohls")
Year <- c(2019, 2020, 2019, 2020)
TrapNumbers <- list(c(1, 9, 2, 3, 6), c(3, 4, 9, 2, 5), c(3, 4, 9, 2), c(1, 9, 2, 3))
NumberofTraps <- c(10, 10, 12, 12)

# Initialize an empty vector to store all TrapCaught values
TrapCaught <- numeric()

# Iterate over the lists of TrapNumbers to combine them into one vector
for (trap_list in TrapNumbers) {
  TrapCaught <- c(TrapCaught, trap_list)
}

# Create the dataframe
DF <- data.frame(Pond = rep(Pond, sapply(TrapNumbers, length)),
                 Year = rep(Year, sapply(TrapNumbers, length)),
                 NumberofTraps = rep(NumberofTraps, sapply(TrapNumbers, length)),
                 TrapCaught = TrapCaught)

手动计算预期结果

  • Aubrees 2019:距离值为[2,1,2,5,3,4,3,1,4,3],中位值=3
  • Aubrees 2020:距离值为[1,4,1,2,5,2,1,3,4,3],中位值=2.5
  • Kohls 2019:距离值为[1,6,1,5,2,5],中位值=3.5
  • Kohls 2020:距离值为[4,1,2,5,6,1],中位值=3

错误代码及问题

以下代码输出的中位值为2、2.5、2.5、2.5,与预期结果不符:

library(dplyr)

# Function to calculate pairwise distances between two vectors
pairwise_distances <- function(x) {
  n <- length(x)
  outer(x, x, "-") %% n
}

# Calculate the median distance for each group
median_distances <- DF %>%
  group_by(Pond, Year) %>%
  summarize(median_distance = median(pairwise_distances(TrapCaught)[upper.tri(pairwise_distances(TrapCaught))]))

# Print the result
print(median_distances)

问题分析与修正方案

错误原因

  1. 取模基数错误:原函数用捕获到小龙虾的陷阱数量length(x)作为环形取模的基数,实际应该用该池塘的总陷阱数(NumberofTraps)。
  2. 未取最短路径:环形距离需要取差值取模后,与总陷阱数的一半比较,保留较小的那个值,才是实际最短距离。

修正后的代码

library(dplyr)

# 修正后的环形成对距离计算函数
pairwise_circular_distances <- function(trap_ids, total_traps) {
  # 生成所有成对差值的绝对值
  diffs <- abs(outer(trap_ids, trap_ids, "-"))
  # 环形取模得到原始距离
  mod_diffs <- diffs %% total_traps
  # 取最短路径:选择环形两侧中较短的距离
  shortest_dists <- pmin(mod_diffs, total_traps - mod_diffs)
  # 提取上三角部分,排除同一陷阱和重复计算的成对组合
  shortest_dists[upper.tri(shortest_dists)]
}

# 分组计算中位距离
median_distances <- DF %>%
  group_by(Pond, Year) %>%
  summarize(
    median_distance = median(pairwise_circular_distances(TrapCaught, first(NumberofTraps))),
    .groups = "drop"  # 取消分组状态
  )

print(median_distances)

运行上述代码后,输出结果将与手动计算的预期值完全一致:

# A tibble: 4 × 3
  Pond    Year median_distance
  <chr>  <dbl>           <dbl>
1 Aubrees  2019             3  
2 Aubrees  2020             2.5
3 Kohls    2019             3.5
4 Kohls    2020             3  

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 18:04:58