使用SparkR计算地理距离

时间:2017-03-13 13:03:44

标签: r apache-spark distance geo

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

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

DataFrame包含两点纬度和经度

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

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

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 个答案:

答案 0 :(得分: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
相关问题