使用sf::st_join做最近邻连接时出现invalid times参数错误求助
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 withst_nnandst_joincompatibility. - If you ever need to match more than one nearest neighbor, just adjust the
kparameter inst_nnand useunnest()to expand the multiple matches. - The
progress = TRUEparameter works fine, but make sure it's passed tost_nn(it's not ast_joinparameter).
内容的提问来源于stack exchange,提问作者Nebulloyd

