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

为何apply函数丢失CRS?如何高效计算点向量地理函数?

问题:apply处理sf对象丢失CRS,求点向量地理计算的最优方法

问题复现

使用apply遍历sf格式的点数据时,会丢失CRS属性,导致地理函数(如st_distance)报错。复现代码如下:

library(tidyverse)
library(sf)

# 生成1000个经纬度点,转为sf格式并设置CRS
df1 <- data.frame(lat = runif(1000, 30, 33.4), long = runif(1000, -95, -82)) %>%
  st_as_sf(coords = c("long", "lat"),
           crs = 4326)

# 单个参考点,设置相同CRS
df2 <- data.frame(lat = 32, long = -96) %>%
  st_as_sf(coords = c("long", "lat"),
           crs = 4326)

# 运行此代码会报错
apply(df1, 1, function(x) st_distance(x, df2))

运行后报错:
Error in st_distance(x, df2) : st_crs(x) == st_crs(y) is not TRUE

但以下两种方式可正常运行:

# 直接取单行计算
st_distance(df1[1,], df2)

# for循环遍历计算
final.df <- NULL
for(i in 1:nrow(df1)){
  ith.distance <- st_distance(df1[i,], df2)
  
  final.df <- rbind(final.df, ith.distance)
}

for循环效率较低,求最优处理方法。

解决方案

报错原因

apply会将sf对象强制转换为普通矩阵/数据框,丢失了sf对象特有的CRS元数据,导致st_distance无法校验两个对象的CRS一致性。

最优方法

直接利用st_distance的向量化特性,无需手动遍历:

# 批量计算df1所有点到df2的距离
distances <- st_distance(df1, df2)

st_distance原生支持批量计算,传入两个sf对象时,会自动计算第一个对象中每个点与第二个对象中每个点的距离,返回矩阵结果。若仅需单个参考点的距离,结果会是列向量,可直接转为数据框:

final.df <- as.data.frame(distances)
colnames(final.df) <- "distance_to_ref_point"

若确实需要逐行处理sf对象,不要用apply,改用sf兼容的purrr系列函数保留属性:

library(purrr)

distances <- map_dbl(df1, ~st_distance(.x, df2))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 01:13:18