使变体

时间:2017-09-20 09:53:00

标签: r function dplyr sparkr sparklyr

通过使用Spark RDD时,我想包装一些常见的转换,以便更方便地将它们传递给mutate语法。

实施例

例如,在处理具有以下时间戳的数据时:

2000-01-01 00:00:00.0
2000-02-02 00:00:00.0

我可以使用以下语法将这些格式转换为更有用的 YYYY-MM-dd 格式:

mutate(nice_date= from_unixtime(unix_timestamp(bad_timestamp), 'YYYY-MM-dd'))

挑战

正如我经常这样做,我想包装from_unixtime(unix_timestamp(bad_timestamp), 'YYYY-MM-dd'))调用并使用语法:

mutate(nice_date = from_unix_to_nice(bad_date))

传统方法建议写一个函数:

from_unix_to_nice<- function(x) {
    from_unixtime(unix_timestamp(x), 'YYYY-MM-dd')
}

问题

应用时,函数失败:

> Error: org.apache.spark.sql.AnalysisException: undefined function
> from_unix_to_nice; line 2 pos 62  at
> org.apache.spark.sql.hive.HiveFunctionRegistry$$anonfun$lookupFunction$2$$anonfun$1.apply(hiveUDFs.scala:69)
>   at
> org.apache.spark.sql.hive.HiveFunctionRegistry$$anonfun$lookupFunction$2$$anonfun$1.apply(hiveUDFs.scala:69)
>   at scala.Option.getOrElse(Option.scala:120)

如何为常见的mutate操作方便地开发包装器,以便将它们传递给sparklyr管道?

1 个答案:

答案 0 :(得分:1)

问题是该函数需要以未评估的方式传递给mutate()函数。可以使用rlang包完成此操作,这是一个示例:

library(rlang)
library(sparklyr) 
library(nycflights13)
library(dplyr)

sc <- spark_connect(master = "local")

just_time <- flights %>%
     select(time_hour) %>%
     mutate(time_hour = as.character(time_hour))
     head(100)

spark_flights <- copy_to(sc, just_time, "flights")


from_unix_to_nice<- function(x) {
  x <- enexpr(x)
  expr(from_unixtime(unix_timestamp(!!x), 'YYYY-MM-dd'))
}

from_unix_to_nice(test)


spark_flights %>%
  mutate(new_field =  !!from_unix_to_nice(time_hour))

from_unix_to_nice()函数现在将from_unixtime(unix_timestamp(test), "YYYY-MM-dd")传递给mutate(),就像您输入了那种确切的语法一样。