在 sparklyr 中导入多个文件

shi*_*han 4 r apache-spark sparklyr

我对 sparklyr 和 spark 很陌生,所以如果这不是执行此操作的“spark”方式,请告诉我。

我的问题

我有 50 多个 .txt 文件,每个文件大约 300 mb,都在同一个文件夹中,称之为x,我需要导入到 sparklyr,最好是一张表。

我可以单独阅读它们

spark_read_csv(path=x, sc=sc, name="mydata", delimiter = "|", header=FALSE)
Run Code Online (Sandbox Code Playgroud)

如果我要将它们全部导入到 sparklyr 之外,我可能会创建一个包含文件名的列表,调用它filelist,然后将它们全部导入到带有 lapply 的列表中

filelist = list.files(pattern = ".txt")
datalist = lapply(filelist, function(x)read.table(file = x, sep="|", header=FALSE)) 
Run Code Online (Sandbox Code Playgroud)

这给了我一个列表,其中元素k是.txt 文件中的第k个 .txt 文件filelist。所以我的问题是:在 sparklyr 中是否有等效的方法来做到这一点?

我试过的

我试过使用lapply()and spark_read_csv,就像我在 sparklyr 外面所做的那样。刚刚更改read.tablespark_read_csv和参数

datalist = lapply(filelist, function(x)spark_read_csv(path = x, sc = sc, name = "name", delimiter="|", header=FALSE))
Run Code Online (Sandbox Code Playgroud)

这给了我一个元素数量与 .txt 文件相同的列表,但每个元素(.txt 文件)都与文件列表中的最后一个 .txt 文件相同。

> identical(datalist[[1]],datalist[[2]])
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

我显然希望每个元素都是数据集之一。我的想法是,在此之后,我可以将rbind它们放在一起。

编辑:

找到了办法。问题是spark_read_csv每次读取新文件时都需要更新参数“name” ,否则它将被覆盖。所以我在 for 循环而不是 lapply 中做了,并且在每次迭代中我更改了名称。有更好的方法吗?

datalist <- list()
for(i in 1:length(filelist)){
  name <- paste("dataset",i,sep = "_")
  datalist[[i]] <- spark_read_csv(path = filelist[i], sc = sc,
  name = name, delimiter="|", header=FALSE)
}
Run Code Online (Sandbox Code Playgroud)

zer*_*323 5

因为你(强调我的)

有 50 多个 .txt 文件,每个文件大约 300 mb,都在同一个文件夹中

您可以在路径中使用通配符:

spark_read_csv(
  path = "/path/to/folder/*.txt",
  sc = sc, name = "mydata", delimiter = "|", header=FALSE) 
Run Code Online (Sandbox Code Playgroud)

如果目录只包含数据,您可以进一步简化:

spark_read_csv(
  path = "/path/to/folder/",
  sc = sc, name = "mydata", delimiter = "|", header = FALSE)
Run Code Online (Sandbox Code Playgroud)

本机 Spark 阅读器还支持一次读取多个路径(Scala 代码):

spark.read.csv("/some/path", "/other/path")
Run Code Online (Sandbox Code Playgroud)

但是从 0.7.0-9014 开始,它在没有正确实现(当前的实现spark_normalize_path不支持大小大于 1 的向量)。