`data.table`能否安全地替代在`sparkR`、`sparklyr`和`rsparkling`中使用的`dplyr`?

3

我正在使用RStudio的Spark扩展之一来刷新我的知识。

坦白地说,无论我看哪里,我都发现dplyr在实现甚至最简单的结果时不必要地复杂,大多数情况下令人痛苦甚至晦涩难懂。

这里是从该网站中获取的一个示例。将mtcars数据集复制到名称为mtcars_tblSpark集群中,然后在筛选出具有100马力以上的汽车时,"tbl_spark"、"tbl_sql"、"tbl_lazy"、"tbl"类表被分成包含于2个组件列表中的traintest子集。

列表名为'partitions',实现它的dplyr代码如下:

 partitions <- mtcars_tbl %>% filter(hp >= 100) %>%
 mutate(cyl8 = cyl == 8) %>%
 sdf_partition(training = 0.5, test = 0.5, seed = 1099)

注意: 在我看来,H2O 的做法更清晰、更具信息量。

然后,在 H2O 平台上训练一个模型,拟合各种汽车重量和气缸配置的“mpg”。

在某个时刻——为了预测目的——需要从测试子集中选择(隔离)列“mpg”,并将其用作数值向量。

以下是针对这么简单的操作实现的 dplyr 代码:

mpg1 <- partitions$test %>% 
                select(mpg) %>% 
                      collect() %>%
                           `[[`("mpg")

...这里是应用于“partitions”列表的data.table代码,清晰、紧凑、简单:

mpg2 <- as.data.frame(partitions$test)[['mpg']]

mpg3 <- as.data.table(partitions$test)[['mpg']]

注意:如果一开始将这两个子集视为dataframedata.table,则代码会更加简洁。

至于比较这三个向量:

identical(mpg1, mpg2, mpg3)

TRUE

all.equal(mpg1, mpg2, mpg3)

TRUE

注意:上面显示的dplyr :: collect()函数实际上会更改mpg1的类别,从

“tbl_spark”“tbl_sql”“tbl_lazy”“tbl”

“tbl_df”“tbl”“data.frame

随后在最后一步中将其转换为数字向量,即'[['('mpg')

嗯,看起来dplyr的代码中有许多多余的步骤。这只是一个简单的例子!

我想知道是否可以安全地绕过dplyr进行R内部的操作,因此我的问题是标题。

注意:我知道一个选项是SQL查询;还有其他(更好的)方法吗?

谢谢!


你不一定需要使用管道符 dplyr。例如,你可以使用 partitions$test[['mpg']] 并提取向量。然而,由于问题涉及到是否适用于 spark 接口,我不确定。但是我知道 dtplyr 延迟收集以实现更高性能的 [tag:data.table] 查询。我只能期望 sparklyr 也会通过惯用的 dplyr 函数序列(即管道链)实现最佳性能。 - Cole
@ Cole:感谢您的评论!我可能没有表达清楚:我认为多余的不仅仅是管道运算符。像“Spark没有data.table接口”这样的评论是无意义的,暗示着忽略了一个事实——正如我的例子所显示的那样——dataframe(通过扩展data.table)与基本提取器[[一起使用。另外,我不确定您的解决方案是否按预期工作;在发布之前,我已经尝试过它,结果是“NULL”。也许在这种情况下,[[需要更深入地挖掘(请参见str(partitions$test))。 - Dragos Bandur
它确实提供了信息,但并不适合解决方案。请参见https://github.com/Rdatatable/data.table/issues/1828。另外,```as.data.table()```的```dtplyr```方法收集并执行查询。根据您的发现,```sparklyr```接口可能也是如此。无论如何,正如您似乎对潜在的优越评论感到沮丧一样,请反思自己的评论。请注意,您没有指出您不喜欢dplyr代码的(主观)原因,让其他人去猜测。我作为一个data.table爱好者说这话。 - Cole
@ Cole,我认为我已经说明了原因:不必要的R基础代码包装导致了不透明性:无论多么复杂,我喜欢我的代码都能表达其意义。为什么需要 mutatetransmutecollect 等等,当已经有数学运算可以实现所有这些功能?此外,用这种方式编写的代码更长,对于大型数据集而言速度也较慢,并且不太容易进行故障排除。是的,我和其他人一样主观!每次阅读教程时,我希望控制我使用的工具。至于链接:请查看这里的表格 - Dragos Bandur
1个回答

0

为什么不使用 pull(partitions$test, mpg)?你的方法并不是使用 dplyr 的惯用方式来执行此操作,所以你感到沮丧也就不足为奇了。

对于 Spark 并没有 data.table 接口。如果你喜欢,可以使用 Spark SQL。 sparklyr 在幕后只是生成了 Spark SQL。

当然,你并不一定要使用 dplyr,但我鼓励你在完全排除它之前更加熟悉其语法——可能有更简洁的方法来做你觉得令人沮丧的事情。


@ bcarlsen谢谢您的回复!我不是要求一次让人感到自大的演讲,而是希望找到有建设性的方法来避免使用dplyr,而不是寻找“惯用的dplyr方式”来操作。我知道SQL的替代方法,也熟悉dplyr语法。 - Dragos Bandur
1
我并不是有意要表现得高人一等。在R中使用dplyr语法的替代方案是Spark SQL。目前还没有使用基础或data.table语法的Spark的R翻译层。 - bcarlsen
@bcarlsed,我并没有说你有故意表现优越的意思! - Dragos Bandur

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接