まず第一に:あなたが安全になりたいのであれば、あなたがリンクしている他の質問からの解決策を使用してください。Rは値による呼び出しであるため、メモリ内のデータフレームをコピーしない「インプレース」メソッドについては忘れてください。
かなりのメモリを節約するための推奨されない方法の1つは、データフレームがリストであると偽って、forループを使用してリストを強制し(適用すると地獄のようにメモリを消費します)、Rに実際にデータフレームであると信じ込ませることです。
もう一度警告します。これをより複雑なデータフレームで使用すると、問題が発生し、バグを見つけるのが困難になります。したがって、十分にテストするようにしてください。可能であれば、これはできるだけ避けてください。
次のアプローチを試すことができます:
n1 <- 1000000
n2 <- 1000000
ncols <- 20
dtf1 <- as.data.frame(matrix(sample(n1*ncols), n1, ncols))
dtf2 <- as.data.frame(matrix(sample(n2*ncols), n1, ncols))
dtf <- list()
for(i in names(dtf1)){
dtf[[i]] <- c(dtf1[[i]],dtf2[[i]])
}
attr(dtf,"row.names") <- 1:(n1+n2)
attr(dtf,"class") <- "data.frame"
それはあなたが実際に持っていた行名を消去します(あなたはそれらを再構築することができますが、重複した行名をチェックしてください!)。また、rbindに含まれる他のすべてのテストを実行するわけではありません。
私のテストではメモリの約半分を節約できます。私のテストでは、dtfcombとdtfの両方が同じです。赤いボックスはrbindで、黄色のボックスは私のリストベースのアプローチです。

テストスクリプト:
n1 <- 3000000
n2 <- 3000000
ncols <- 20
dtf1 <- as.data.frame(matrix(sample(n1*ncols), n1, ncols))
dtf2 <- as.data.frame(matrix(sample(n2*ncols), n1, ncols))
gc()
Sys.sleep(10)
dtfcomb <- rbind(dtf1,dtf2)
Sys.sleep(10)
gc()
Sys.sleep(10)
rm(dtfcomb)
gc()
Sys.sleep(10)
dtf <- list()
for(i in names(dtf1)){
dtf[[i]] <- c(dtf1[[i]],dtf2[[i]])
}
attr(dtf,"row.names") <- 1:(n1+n2)
attr(dtf,"class") <- "data.frame"
Sys.sleep(10)
gc()
Sys.sleep(10)
rm(dtf)
gc()