r语言 - 清理代码并防止空值崩溃读取.csv.sql



我正在使用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 }'))

的主要问题是,如果上面的任何值(来自 UI(为 null,那么它将无法正确读取数据,因为这块代码都是硬编码的。
我想将其更改为:步骤1 - 检查哪些值为空并且不要过滤掉它们,然后使用read.csv.sql过滤相应列上的所有非空值。

注意:我在这个问题中重用了这个类似问题中的代码。

更新
我想澄清我在问什么。这就是我要做的:

如果一个字段,比如说specNA的形式通过(意味着用户没有选择输入(,那么我希望它像这样过滤(默认为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 }'))

由于specNA,如果您尝试过滤/读取与spec == NA匹配的文件,它将读取空数据集,因为我的数据中没有 NA 值,从而破坏代码和程序。希望这能进一步澄清它。

有几个问题:

  • 问题链接中提供的一些简化没有遵循。
  • spec是一个标量,所以人们可以使用'$spec'
  • petwd是一个数字标量,SQL不需要在数字周围加上引号,所以只需使用$petwd
  • 问题指出您想要处理空字段,但不知道如何处理,因此我们使用 csvfix 将它们映射到 -1 并去除引号。 (或者让他们进入并在 R 中执行此操作。 空数字将以 0 表示,空字符字段将以零长度字符字段表示。
  • 您可以使用 [...] 代替"..."在 SQL 中

下面的代码在Windows和Ubuntu Linux中使用bash shell对我有用。

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。 在这种情况下,只需展开 SQLwhere条件即可处理,如下所示。

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 的所有行。

最新更新