是否有一种简单的方法可以使用RSQLite和`sqldf`以及超过999个变量?

时间:2011-11-06 10:08:29

标签: sqlite r

是否有一种简单的方法可以将RSQLitesqldf与999个变量一起使用?

同样提出了这个问题here。关于R-sig-DB的答案

“这不起作用的原因似乎是sqlite源码中的SQLITE_MAX_VARIABLE_NUMBER(在RSQLite中)当前设置为999。”

以下是一些示例代码:

# works fine
widedf <- rnorm(2*998)
dim(widedf) <- c(2, 998)
f2 <- tempfile()
write.csv(widedf, f2, quote = FALSE)

f2 <- file(f2)
widedf <- sqldf("select * from f2", 
                dbname = tempfile(), 
                file.format = list(header = T, row.names = F))

# doesn't work
widedf <- rnorm(2*1000)
dim(widedf) <- c(2, 1000)
f1 <- tempfile()
write.csv(widedf, f1, quote = FALSE)

f1 <- file(f1)
widedf <- sqldf("select * from f1", 
                dbname = tempfile(), 
                file.format = list(header = T, row.names = F))
# Error in try({ : 
#  RS-DBI driver: (RS_sqlite_import: too many SQL variables)

在这种情况下有哪些选择?

1 个答案:

答案 0 :(得分:6)

sqldf也适用于某些其他数据库。尝试使用sqldf支持的H2 java数据库,该数据库具有csvread函数。如果您还没有安装java,请安装RH,然后安装RH2包(其中包含H2本身,因此无需安装)。

第一种方法

library(RH2)
library(sqldf)

# create test file
widedf <- as.data.frame(matrix(rnorm(2*1000), 2))
write.csv(widedf, "widedf.csv", row.names = FALSE)

# fac2num is defined on sqldf home page in FAQ #10
w.out <- sqldf("select * from csvread('widedf.csv')", method = fac2num)

第二种方法

第二种替代方法是在H2中设置类型而不是使用fac2num。第一行使用widedf.csv仅读取read.csv的第一行,甚至删除它,以便我们获得一个空数据帧但具有正确的列类。第二行将widedf.csv文件插入widedf0,然后在两个sql语句的第二行中选择它,以便sqldf调用的结果是新表。

widedf0 <- read.csv("widedf.csv", nrows = 1)[0L, ]
w2.out <- sqldf(c("insert into widedf0 (select * from csvread('widedf.csv'))", 
    "select * from widedf0"))

在上述情况下,sqldf会注意到RH2已加载并假设您要使用H2作为后端数据库。 (sqldf包还有一个drv参数和一个sqldf.driver选项,其中任何一个都可用于强制特定的后端,无论加载什么。)

sqldf home pageFAQ #10上还有一些使用来自sqldf的H2 csvread的其他示例。

如果您真的想使用RSQLite包作为后端,那么您可以与RSQLite包维护者讨论是否可以增加999限制,或者您可以构建具有更高限制的RSQLite的私有版本。

编辑:

上面修改了代码以使用fac2num,并且还说明了从H2设置列类型的第二种方法。请参阅FAQ #10