通过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管道?
答案 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()
,就像您输入了那种确切的语法一样。