2

我正在尝试在 R 中对一组中型数据集进行数据分析。我需要做的一项分析要求我对大约 24-48 个文件进行完全外部连接,每个文件有大约 60 列和多达 450,000 行。所以我经常遇到内存问题。

我认为 ffbase 或 sqldf 会有所帮助,但显然它们中的任何一个都不可能完全外连接。

有解决方法吗?我还没有找到的包裹?

4

4 回答 4

7

这是一个简单的示例,说明了如何对多个数据集进行外部连接:

library(sqldf)
dat1 <- data.frame(x = 1:5,y = letters[1:5])
dat2 <- data.frame(w = 3:8,z = letters[3:8])
> 
> sqldf("select * from dat1 left outer join dat2 on dat1.x = dat2.w UNION 
+       select * from dat2 left outer join dat1 on dat1.x = dat2.w")
  x y  w    z
1 1 a NA <NA>
2 2 b NA <NA>
3 3 c  3    c
4 4 d  4    d
5 5 e  5    e
6 6 f NA <NA>
7 7 g NA <NA>
8 8 h NA <NA>

就是这样,使用sqldf和 SQLite 作为后端的完整外连接。

正如我还提到的,sqldf支持比 SQLite 更多的后端。一次 Google 搜索显示完全外连接在 MySQL 中以完全相同的方式完成。我对 postgres 不太熟悉,但这个问题肯定表明在那里也可以进行完整的外部连接。

于 2013-06-08T20:01:39.390 回答
4

没有 sqldf,这是一个聪明而简单的解决方案:

合并(a, b, by = "col", all = T)

外汇

于 2014-10-15T13:46:12.317 回答
0

如果您使用的是 ffbase,如果您将 expand.ffgrid 与 merge.ffdf 结合使用,则可以获得所需的完全外连接结果。expand.ffgrid 类似于 expand.grid 但与 ff 向量一起使用,因此它不会溢出您的 RAM,merge.ffdf 允许与另一个 ffdf 合并而不会溢出您的 RAM 并将数据存储在磁盘上。下面是一个例子。

require(ffbase)
x <- ffseq(1, 10000)
y <- ff(factor(LETTERS))
allcombinations <- expand.ffgrid(x, y)
addme <- data.frame(Var1 = c(1, 2), Var2 = c("A","B"), measure = rnorm(2))
addme <- as.ffdf(addme)
myffdf <- merge(allcombinations, addme, by.x=c("Var1","Var2"), by.y=c("Var1","Var2"),  all.x=TRUE)
myffdf[1:10,]

接下来,查看删除行 ff 包,了解如何对生成的 myffdf 进行子集化。

看看 ?ffbase::expand.ffgrid 和 ?ffbase::merge.ffdf

于 2013-06-09T10:18:00.010 回答
0

这可能有效(注意:关键列必须是每个数据集中的第一列)。

library(ff)
library(ffbase)

fullouterjoin <- function(ffdf1, ffdf2){

    # do a left outer join
    leftjoin <- merge(ffdf1, ffdf2, by = "key", all.x = TRUE)

    # do a right outer join (it's just a left outer join with the objects swapped)
    rightjoin <- merge(ffdf2, ffdf1, by = "key", all.x = TRUE)

    # swap the column orders (make ffd1 columns first and ffd2 columns later)
    srightjoin <- rightjoin[c(names(ffdf1), names(ffdf2)[2:length(ffdf2)])]

    # stack left outer join on top of the (swapped) right outer join
    stacked <- rbind(leftjoin, srightjoin)

    # remove duplicate rows
    uniques <- unique(stacked)

    # that's it
    return(uniques)
}

用法:

newffdf <- fullouterjoin(some_ffdf, another_ffdf)

我并不是说它很快,但它可能会克服内存障碍。

于 2013-11-29T04:27:17.933 回答