我正在使用read.csv.sql
有条件地读取数据(我的数据集非常大,所以这是我选择的一种解决方案,在读取数据之前先对其进行过滤并减小其大小)。通过读取完整数据然后进行过滤,我遇到了内存问题,这就是为什么使用条件读取以便读取子集而不是完整数据集很重要的原因。
这是一个小的数据集,因此可以重现我的问题:
write.csv(iris, "iris.csv", row.names = F)
library(sqldf)
csvFile <- "iris.csv"
使用read.csv.sql
后,我发现您必须使用的符号极其尴尬,以下是我在文件中的读取方式:
# Step 1 (Assume these values are coming from UI)
spec <- 'setosa'
petwd <- 0.2
# Add quotes and make comma-separated:
spec <- toString(sprintf("'%s'", spec))
petwd <- toString(sprintf("'%s'", petwd))
# Step 2 - Conditionally read in the data, store in 'd'
d <- fn$read.csv.sql(csvFile, sql='select * from file where
"Species" in ($spec)'
and "Petal.Width" in ($petwd)',
filter = list('gawk -f prog', prog = '{ gsub(/"/, ""); print }'))
我的 main 问题是,如果上面的任何值(来自UI)为null,则它将无法正确读取数据,因为这部分代码都是硬编码的。 />
我想将其更改为:步骤1-检查哪些值是空值并且不从中过滤掉,然后使用read.csv.sql
过滤对应列上的所有非空值。
注意:我正在此问题中重复使用此similar question中的代码。
更新
我想弄清楚我的要求。这就是我想要做的:
如果某个字段说spec
为NA
(表示用户未选择输入),那么我希望它按这样进行过滤(默认为spec == EVERY SPEC
):>
# Step 2 - Conditionally read in the data, store in 'd'
d <- fn$read.csv.sql(csvFile, sql='select * from file where
"Petal.Width" in ($petwd)',
filter = list('gawk -f prog', prog = '{ gsub(/"/, ""); print }'))
由于spec
是NA
,如果您尝试过滤/读取匹配spec == NA
的文件,由于我的数据中没有NA值,它将读取一个空数据集,因此破坏了代码和程序。希望这能进一步清除它。
答案 0 :(得分:0)
有几个问题:
spec
是一个标量,因此只能使用'$spec'
petwd
是一个数字标量,SQL不需要数字引号,因此只需使用$petwd
下面的代码通过bash shell在Windows和Ubuntu Linux中都对我有用。
library(sqldf)
spec <- 'setosa'
petwd <- 0.2
d <- fn$read.csv.sql(
"iris.csv",
sql = "select * from file where [Species] = '$spec' and [Petal.Width] = $petwd",
verbose = TRUE,
filter = 'csvfix map -smq -fv "" -tv -1'
)
关于问题末尾的更新,已澄清了NA可能位于spec
中,而不是位于要读取的数据中,并且如果spec
为NA,则涉及的条件spec
应该被视为TRUE。在这种情况下,只需展开SQL where
条件即可,如下所述。
spec <- NA
petwd <- 0.2
d <- fn$read.csv.sql(
"iris.csv",
sql = "select * from file
where ('$spec' == 'NA' or [Species] = '$spec') and [Petal.Width] = $petwd",
verbose = TRUE,
filter = 'csvfix echo -smq'
)
上面的代码将返回Petal.Width
为0.2的所有行。