R结合FF基和Sqldf

Posted

技术标签:

【中文标题】R结合FF基和Sqldf【英文标题】:R combining FF base and Sqldf 【发布时间】:2013-07-04 13:59:54 【问题描述】:

到目前为止,我一直在使用 Sqldf 和 R 函数的组合来管理我的数据集。但是,我需要在大型数据集上执行一堆左连接,即使使用 sqldf dbname=tempfile(),我也会开始耗尽内存。

我注意到 FF 的第一件事是我无法将它传递给 sqldf。我注意到的第二件事是我的典型函数并不都在 ff 中工作。

我的正常加入示例

base <- read.csv(filename)
base <- sqldf("select * from base where DATE > 20120101")

for (j in list.files())
   temp <- read.csv(tempfile)
   temp <- sqldf("select MATCH_KEY, DATE from temp")
   base <- sqldf("select * from base NATURAL LEFT OUTER JOIN temp")
 

对于 ffbase,我不能简单地使用“as.ffdf(temp)”。解决方法是编写一个物理临时文件,然后将其作为 ff 读入,然后与 ff-s 进行合并。我觉得这不是与 ff 合作的好方法。有更好的选择吗?

我面临的第二个问题可能是由于我对 ff 的陌生。我有一个简单的代码,只是不知道如何在 ff 中实现。基本上我有数据框基础,我想循环并计算值大于某个数字的次数。使用我的日期示例的想法(实际上我也在检查数字、比率等,但想法始终相同)。

checks <- c(20010101,20020101,20030101)
summary <- matrix(0,ncol=dim(base)[2],nrow=length(checks))

for (i in checks)
  for (j in dim(base)[2])
     summary[i,j]<-sum(base[,j]>=i)

这些函数也不适用于 ff。现在我实际上正在使用 sqldf 读取文件,然后写入一个临时文件。用 ff 读那些,然后做所有的合并业务。然后,我再次写入一个临时文件,并将其作为普通文件读回。哎呀!有什么改进建议吗?

[编辑]

一个大问题是,如何使用 as.ffdf 转换通过 sqldf (temp

另外,我似乎无法在 ff 中使用的两个函数示例。

1) 我经常用 0 替换文件中的缺失值,以将它们与合并创建的缺失区分开来。我这样做是通过

   DF[is.na(DF)] <- 0

使用 ff 似乎有点复杂,我担心失去可读性:Replace NAs in a ffdf object

2) 对列或行求和,寻找特定值。例如,计算“R”在列中出现的次数。在ff中?

【问题讨论】:

对于您的第一个问题,as.ffdf(temp) 应该可以。你得到什么错误? 对于第二个问题,你应该给出一个你的“基础”表,你在ff中尝试了什么(你得到了什么错误) 使用 as.ffdf 时,错误说明了有关字符 vmode 的内容。对于第二个问题,我的大部分计算都是使用 ifelse 和对行求和的组合。行的总和在 ff 中不起作用。 sum(ff[,rowNum]>=5) --> 无效 试试这个:BODff &lt;- as.ffdf(BOD); class(BODff) &lt;- c("ffdf" , "data.frame"); sqldf("select * from BODff", method = "raw")。请注意,sqldf 语句将返回一个数据框,因此如果您想要一个 ff 对象,则必须使用as.ffdf 对其进行转换。还需要method = "raw",但这意味着它不会像sqldf 通常那样进行某些自动转换。 SQL 在更改类后会看到 ffdf,即使没有指定方法。谢谢!但是,为什么? 【参考方案1】:

对于第一个问题。你为什么不这样做?

require(ffbase)
base <- read.csv.ffdf(filename)
open(base)
base <- subset(base, DATE > 20120101)

for (j in list.files())
  temp <- read.csv.ffdf(tempfile, transFUN=function(x)
    x[c("MATCH_KEY","DATE")]
  )
  base <- merge(base, temp, by.x="MATCH_KEY", by.y="MATCH_KEY", all.x=TRUE)

为了使 sqldf 与 ffdf 对象一起工作,sqldf 中可能需要进行一些更改,即在它将数据从 ffdf 推送到 sqlite 的地方,这需要分块完成,这样它就不会溢出 RAM。此外,在 sqldf 中提取回 R 中的 ffdf 应该以不同方式处理(可能通过使用 ETLUtils 中的 read.dbi.ffdf) - 可能将此作为更改请求向 sqldf 包作者询问。

关于您的第二个问题,请务必展示您使用 ff 尝试过的内容以及您停止进一步尝试的地方。因为您在问题中指出的内容完全可以使用 ff。

【讨论】:

我避免使用 read.csv.ffdf 因为你不能指定分隔符。 (你可以吗?)根据文件类型“;”,我有不同分隔符的文件为一个,“^”为其他,等等。 使用 read.table.ffdf 然后如果您需要指定分隔符并且文件不是严格的 csv。 感谢您的提示!在法国,CSV 意味着用“;”分隔,它是 excel 的默认选项。我往往会收到很多带有奇怪分隔符的文件。

以上是关于R结合FF基和Sqldf的主要内容,如果未能解决你的问题,请参考以下文章

将 RpostgreSQL 与 sqldf 一起使用会使 R 崩溃

R中利用SQL语言读取数据框(sqldf库的使用)

r 使用R中的sqldf将CSV导入Sqlite

在R中的sqldf中将整数转换为字符串

R SQLDF 仅提取一个值

可以使用sqldf将数据库中已经存在的表的数据导入R中的data.frame吗?