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

使用sf::st_join做最近邻连接时出现invalid times参数错误求助

Fixing invalid 'times' argument Error with sf::st_join() + st_nn

Hey there, that error you're hitting comes down to a small misstep in how you're passing arguments to st_nn through st_join. Let's break it down and fix it:

The Root Cause

When you add returnDist = TRUE directly in your st_join call, you're telling st_nn to return a nested list containing both neighbor indices and distances instead of just the index list that st_join expects. This mismatch causes the internal rep() function to receive invalid "times" values, hence the error.

Solution 1: Step-by-Step Join + Distance Calculation

We'll split the process into two clear steps: fetching nearest neighbor info, then merging the data manually. This gives you full control over the output:

# First, get nearest neighbor indices and distances directly from st_nn
nn_results <- st_nn(x1, x2, maxdist = Inf, returnDist = TRUE, k = 1)
# k=1 ensures we only grab the closest neighbor (default, but explicit is clearer)

# Merge x2's attributes and the distance into x1
x1_joined <- x1 %>%
  mutate(
    PairID = x2$PairID[unlist(nn_results$nn)],
    nearest_distance = unlist(nn_results$dist)
  )

# For your batch processing with the sf.eSPDF list:
big_join <- lapply(sf.eSPDF, function(x) {
  nn_res <- st_nn(x, sf.plt.centr, maxdist = Inf, returnDist = TRUE, k = 1)
  x %>%
    mutate(
      PairID = sf.plt.centr$PairID[unlist(nn_res$nn)],
      nearest_distance = unlist(nn_res$dist)
    )
})

Solution 2: Join First, Calculate Distances After

If you prefer sticking closer to the st_join workflow, you can complete the join first, then compute the distances separately:

# Perform the nearest neighbor join (no returnDist here!)
x1_joined <- st_join(x1, x2, join = st_nn, maxdist = Inf, k = 1)

# Calculate distances between each point and its matched neighbor
x1_joined$nearest_distance <- st_distance(
  x1_joined, 
  sf.plt.centr[match(x1_joined$PairID, sf.plt.centr$PairID), ],
  by_element = TRUE
)

# Batch version for your list:
big_join <- lapply(sf.eSPDF, function(x) {
  joined_data <- st_join(x, sf.plt.centr, join = st_nn, maxdist = Inf, k = 1)
  joined_data$nearest_distance <- st_distance(
    joined_data, 
    sf.plt.centr[match(joined_data$PairID, sf.plt.centr$PairID), ],
    by_element = TRUE
  )
  joined_data
})

Why Your Original Code Failed

When you passed returnDist = TRUE to st_join, st_nn returned a list with two elements: nn (the indices) and dist (the distances). st_join expects a simple list of indices, so it tried to use this nested list to generate matches, leading to the rep() function getting invalid "times" values (since it was looking at the length of the nested list instead of the per-point index lists).

Quick Extra Tips

  • Make sure you're running the latest version of sf—older versions had bugs with st_nn and st_join compatibility.
  • If you ever need to match more than one nearest neighbor, just adjust the k parameter in st_nn and use unnest() to expand the multiple matches.
  • The progress = TRUE parameter works fine, but make sure it's passed to st_nn (it's not a st_join parameter).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:16:48