问题
我必须对分组和有序 (大) spark 数据框上的几列进行累计求和。我以前用 base::cumsum() 和 dplyr::mutate_at() 来做,效果很好。此会话不再有效 信息:
会话信息()
R version 4.4.1 (2024-06-14)
spark_version = "3.5.0"
sparklyr_1.8.4 dbplyr_2.4.0 dplyr_1.1.4
可重现的示例
library("dplyr"); library("sparklyr"); library("dbplyr")
spark_version = "3.5.0"
sc = spark_connect(master = "local", version = spark_version)
# --- copying mtcars data into spark for the example
sdf_mtcars = sdf_copy_to(sc = sc, x = mtcars, name = "sdf_mtcars", overwrite = TRUE)
sdf_mtcars %>% group_by(cyl) %>%
window_order(disp) %>%
mutate_at(.vars = 'mpg', .funs = cumsum) %>%
ungroup() %>%
collect()
但它会产生错误:
Error in `mutate()`:
ℹ In argument: `mpg = .Primitive("cumsum")(mpg)`
Caused by error in `mutate_at()`:
! object 'mpg' not found
如果我使用 sum() 而不是 cumsum(),它工作正常。如果我这样做,它也可以正常工作:
mutate("mpg_cumulative" = cumsum(mpg))
但我必须在向量内的几个命名列上执行此操作(例如:在我的示例中为 c('mpg'))
如果我这样做,它就可以正常工作:
mutate_at(.vars = 'mpg', .funs = ~ cumsum(.)) %>%
但是语法有点奇怪?
谢谢。
我正在使用 Databricks,因此设置略有不同,但它是 Spark 3.5.0。
现在来谈谈实际问题。按照@Limey 的建议,使用
dplyr::across
。我也总是建议
dplyr::show_query
确保它能做你真正想要的事情:另外,如果你真的想使用
mutate_at
,你只需要使用tidyselect最后,这种语法
~ cumsum(.)
只是匿名函数的 tidyverse 风格,尽管从技术上讲它应该是.funs = ~ cumsum(.x)
。