首页 文章

使用SparkR计算地理距离

提问于
浏览
1

我在R中有一个Spark数据帧,如下所示

head(df)
Lat1    Lng1    Lat2    Lng2
23.123  24.234  25.345  26.456
...     ...     ...     ...

DataFrame 包含两个纬度和经度点

我想计算每行节点之间的地理距离,并将其添加到新列 .

在R我正在使用 geosphere 库中的 distCosine 函数 .

df$dist = distCosine(cbind(df$lng1,df$lat1),cbind(df$lng2,df$lat2))

我想知道如何在SparkR中计算它 .

SparkR产生以下错误,

Error in as.integer(length(x) > 0L) : 
cannot coerce type 'S4' to vector of type 'integer'

1 回答

  • 1

    您不能直接在Spark DataFrames 上使用标准R功能 . 如果你使用最近的Spark版本,你可以使用 dapply ,但它有点冗长和缓慢:

    df <- createDataFrame(data.frame(
      lat1=c(23.123), lng1=c(24.234),  lat2=c(25.345),  lng2=c(26.456)))
    
    new_schema <- do.call(
      structType, c(schema(df)$fields(), list(structField("dist", "double", TRUE))))
    
    attach_dist <- function(df) {
      df$dist <- geosphere::distCosine(
        cbind(df$lng1, df$lat1), cbind(df$lng2, df$lat2))
      df
    }
    
    dapply(df, attach_dist, new_schema) %>% head()
    
    lat1   lng1   lat2   lng2     dist
    1 23.123 24.234 25.345 26.456 334733.4
    

    在实践中,我宁愿直接使用公式 . 它会快得多,所有必需的功能都已经可用,而且不是很复杂:

    df %>% withColumn("dist", acos(
      sin(toRadians(df$lat1)) * sin(toRadians(df$lat2)) + 
      cos(toRadians(df$lat1)) * cos(toRadians(df$lat2)) * 
      cos(toRadians(df$lng1) - toRadians(df$lng2))
    ) * 6378137) %>% head()
    
    lat1   lng1   lat2   lng2     dist
    1 23.123 24.234 25.345 26.456 334733.4
    

相关问题