我正在尝试在 R 中对一组中型数据集进行数据分析。我需要做的一项分析要求我在大约 24-48 个文件中进行完整的外部联接,每个文件大约有 60 列和最多 450,000 行。所以我经常遇到内存问题。
我认为 ffbase 或 sqldf 会有所帮助,但显然它们中的任何一个都不可能实现完全外连接。
有解决办法吗?我还没有找到的包?
这是一个简单的示例,说明如何对多个数据集进行外连接:
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 不太熟悉,但是this问题表明那里也可以实现完整的外连接。
合并(a,b,by =“col”,全部= T)
外汇
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,]
接下来,查看delete rows ff package
了解如何对生成的 myffdf 进行子集化。 看看 ?ffbase::expand.ffgrid 和 ?ffbase::merge.ffdf
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)
我并不是说它很快,但它可能会克服内存障碍。