21

我有两个数据框df1df2每个都有大约 1000 万行和 4 列。我使用 RODBC/sqlQuery 将它们读入 R 没有问题,但是当我尝试rbind它们时,我得到了最可怕的 R 错误消息:cannot allocate memory. 必须有更有效的方法来更有效地做事rbind——有人想分享他们最喜欢的技巧吗?例如,我在文档中找到了这个例子sqldf

# rbind
a7r <- rbind(a5r, a6r)
a7s <- sqldf("select * from a5s union all select * from a6s")

这是最好的/推荐的方法吗?

更新 我使用dbname = tempfile()中的关键参数sqldf,正如 JD Long 在他对这个问题的回答中所建议的那样

4

4 回答 4

26

与其在开始时将它们读入 R 然后组合它们,您可以让 SQLite 在将它们发送到 R 之前读取它们并组合它们。这样,文件永远不会单独加载到 R 中。

# create two sample files
DF1 <- data.frame(A = 1:2, B = 2:3)
write.table(DF1, "data1.dat", sep = ",", quote = FALSE)
rm(DF1)

DF2 <- data.frame(A = 10:11, B = 12:13)
write.table(DF2, "data2.dat", sep = ",", quote = FALSE)
rm(DF2)

# now we do the real work
library(sqldf)

data1 <- file("data1.dat")
data2 <- file("data2.dat")

sqldf(c("select * from data1", 
 "insert into data1 select * from data2", 
 "select * from data1"), 
 dbname = tempfile())

这给出了:

>  sqldf(c("select * from data1", "insert into data1 select * from data2", "select * from data1"), dbname = tempfile())
   A  B
1  1  2
2  2  3
3 10 12
4 11 13

如果行顺序不重要,这个较短的版本也可以工作:

sqldf("select * from data1 union select * from data2", dbname = tempfile())

有关更多信息,请参阅 sqldf 主页http://sqldf.googlecode.com?sqldf。请特别注意文件格式参数,因为它们与read.table. 在这里,我们使用了默认值,因此问题不大。

于 2011-01-21T17:26:00.593 回答
20

请注意data.tableR 包,用于对具有数百万条记录的对象进行有效操作。

该软件包的 1.8.2 版提供了rbindlist您可以非常有效地实现您想要的功能的功能。因此,rbind(a5r, a6r)您可以:

library(data.table)
rbindlist(list(a5r, a6r))
于 2012-08-27T19:34:22.253 回答
1

尝试创建data.frame所需大小的,因此使用下标导入数据。

dtf <- as.data.frame(matrix(NA, 10, 10))
dtf1 <- as.data.frame(matrix(1:50, 5, 10, byrow=TRUE))
dtf2 <- as.data.frame(matrix(51:100, 5, 10, byrow=TRUE))
dtf[1:5, ] <- dtf1
dtf[6:10, ] <- dtf2

我猜想rbind在没有预先分配其尺寸的情况下增长对象......我不确定,这只是一个猜测。今晚我将梳理“The R Inferno”或“R 的数据操作”。也许merge会做的伎俩...

编辑

而且您应该记住,(也许)您的系统和/或 R 无法应对那么大的事情。试试 RevolutionR,也许你会设法节省一些时间/资源。

于 2011-01-21T16:56:56.293 回答
1

为了使本线程中关于 union:ing 大文件的主题保持完整,请尝试在文件上使用 shell 命令来组合它们。在带有“/B”标志的“COPY”命令的窗口中。例子:

system(command =
         paste0(
           c("cmd.exe /c COPY /Y"
             , '"file_1.csv" /B'
             , '+ "file_2.csv" /B'
             , '"resulting_file.csv" /B'
           ), collapse = " "
         )
)#system

要求文件没有标题,以及相同的分隔符等。shell 命令的速度和多功能性有时是一个很大的好处,所以在映射数据流时不要忘记 CLI 命令。

于 2016-07-08T09:31:18.863 回答