r 中 read.csv.sql 的符号问题

Notation issues with read.csv.sql in r

我正在使用 read.csv.sql 有条件地读入数据(我的数据集非常大,所以这是我选择过滤它并缩小它的解决方案 先于 读取中的数据。我 运行 通过读取完整数据然后过滤它来解决内存问题,这就是为什么我使用条件读取很重要,以便读取子集而不是完整数据集。
这是一个小数据集,所以我的问题可以重现:

write.csv(iris, "iris.csv", row.names = F)

我发现使用 read.csv.sql 时你必须使用的符号非常笨拙以下是我尝试读取文件的第一种方法,它有效但很混乱:

library(sqldf)
csvFile <- "iris.csv"

spec <- 'setosa'
sql <- paste0("select * from file where Species = '\"", spec,"\"'")
d1 <- read.csv.sql(file = csvFile, sql = sql)

然后我找到了另一种以更简洁的方式编写相同符号的方法:

sql <- paste0("select * from file where Species = '", spec,"'")
d2 <- read.csv.sql(file = csvFile, sql = sql, 
                   filter = list('gawk -f prog', prog = '{ gsub(/"/, ""); print }'))

接下来,我想在 select 来自同一列的多个值的情况下读取,所以我尝试了这个并且它有效:

d3 <- read.csv.sql(file = csvFile, 
                   sql = "select * from file where Species in 
                         ('\"setosa\"', '\"versicolor\"') ")

但是,我想避免像这样对值进行硬编码,所以我尝试了:

spec2 <- c('setosa', 'versicolor')
sql2 <- paste0("select * from file where Species in '", spec2,"'")
d4 <- read.csv.sql(file = csvFile, sql = sql2, 
                   filter = list('gawk -f prog', prog = '{ gsub(/"/, ""); print }'))

但这不起作用(它似乎只从向量中读取第一个值并尝试将其匹配为 table)。我确定这又是另一个符号问题,希望帮助清理这段代码。
此外,如果您有任何关于使用 read.csv.sql 和处理符号问题的 tips/tricks,我想听听他们的意见!

问题是 sqldf 提供了文本预处理工具,但问题中显示的代码没有使用它们,这使得它过于复杂。

1) 关于文本替换,使用 fn$(来自 sqldf 自动加载的 gsubfn),如 github page for sqldf 中所述。假设我们在 write.csv 中使用了 quote = FALSE,因为 sqlite 本身不处理引号:

spec <- 'setosa'
out <- fn$read.csv.sql("iris.csv", "select * from file where Species = '$spec' ")

spec <- c("setosa", "versicolor")
string <- toString(sprintf("'%s'", spec)) # add quotes and make comma-separated
out <- fn$read.csv.sql("iris.csv", "select * from file where Species in ($string) ")

2) 关于删除双引号,更简单的方法是使用以下 filter= 参数:

read.csv.sql("iris.csv", filter = "tr -d \042") # Windows

read.csv.sql("iris.csv", filter = "tr -d \\042") # Linux / bash

取决于您的 shell。第一个在 Windows 上为我工作(安装了 Rtools 并在 PATH 上),第二个在 Linux 和 bash 上为我工作。其他 shell 可能需要其他变体。

2a) 另一种删除引号的方法是在您的系统上安装免费的 csvfix 实用程序(在 Windows, Linux and Mac 上可用),然后使用以下 filter= 参数应该适用于所有 shells,因为它不涉及通常由 R 或大多数 shells 专门解释的任何字符。因此,以下内容应该适用于所有平台。

read.csv.sql("iris.csv", filter = "csvfix echo -smq")

2b) 另一个可以使用的跨平台实用程序是 xsveol= 参数仅在 Windows 上需要,因为 xsv 生成 UNIX 风格的行结尾但不会在其他平台上造成伤害,因此以下行应该适用于所有平台。

read.csv.sql("iris.csv", eol = "\n", filter = "xsv fmt")

2c) sqldf还包含一个awk程序(csv.awk)可以使用。它输出 UNIX 样式的换行符,因此在 Windows 上指定 eol = "\n"。在其他平台上,如果您指定它不会有什么坏处,但如果您愿意,可以省略它,因为这是这些平台上的默认设置。

csv.awk <- system.file("csv.awk", package = "sqldf")
rm_quotes_cmd <- sprintf('gawk -f "%s"', csv.awk)
read.csv.sql("iris.csv", eol = "\n", filter = rm_quotes_cmd)

3) 关于一般提示,请注意 read.csv.sqlverbose=TRUE 参数对于了解发生了什么很有用。

read.csv.sql("iris.csv", verbose = TRUE)