我正在使用read.csv.sql
有条件地读取数据(我的数据集非常大,所以这是我选择过滤并减小大小的解决方案 之前的< / strong> 读取其中的数据)。我遇到了内存问题,方法是读取完整数据,然后对其进行过滤,因此这就是为什么使用条件读取以便读取子集而不是完整数据集很重要的原因。
这是一个小数据集,因此可以重现我的问题:
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 }'))
接下来,我想在从同一列中选择多个值的情况下进行阅读,因此我尝试了此操作,并且可以正常工作:
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 }'))
但是这不起作用(它似乎只从向量中读取第一个值,并尝试将其匹配为表)。我确定这又是一个符号问题,希望能帮助您清除这段代码。
另外,如果您有使用read.csv.sql
和处理符号问题的任何提示/技巧,我想听听他们的意见!
答案 0 :(得分:3)
问题在于sqldf提供了文本预处理功能,但问题中显示的代码并未使用它们,因此使其过于复杂。
1)关于文本替换,如github page for sqldf所述,使用fn$
(从sqldf自动加载的gsubfn)。假设我们在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
取决于您的外壳。第一个在Windows上为我工作(安装了Rtools,并在PATH上),第二个在Linux上使用bash为我工作。其他外壳可能需要其他变体。
2a)删除引号的另一种可能性是在系统上安装免费的csvfix实用程序(在Windows,Linux和Mac上可用)请使用以下filter=
参数,该参数应在所有shell中都有效,因为它不包含任何通常由R或大多数shell专门解释的字符。因此,以下内容应在所有平台上均适用。
read.csv.sql("iris.csv", filter = "csvfix echo -smq")
2b)另一个可以使用的跨平台实用程序是xsv。 eol=
参数仅在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),关于一般性提示,请注意,verbose=TRUE
的{{1}}自变量可能有助于了解其运行情况。
read.csv.sql