如何在不增加内存消耗的情况下绑定data.table?

时间:2016-01-13 08:28:19

标签: r data.table rbind

我有几个巨大的数据表dt_1, dt_2, ..., dt_N具有相同的cols。我想将它们绑定到一个datatable。如果我使用

dt <- rbind(dt_1, dt_2, ..., dt_N)

dt <- rbindlist(list(dt_1, dt_2, ..., dt_N))

然后内存使用量大约是dt_1,dt_2,...,dt_N所需数量的两倍。有没有办法绑定它们,而不会显着增加内存消耗?请注意,一旦将它们组合在一起,我就不需要dt_1, dt_2, ..., dt_N

3 个答案:

答案 0 :(得分:5)

其他方法,使用临时文件“绑定”:

nobs=10000
d1 <- d2 <- d3 <-  data.table(a=rnorm(nobs),b=rnorm(nobs))
ll<-c('d1','d2','d3')
tmp<-tempfile()

# Write all, writing header only for the first one
for(i in seq_along(ll)) {
  write.table(get(ll[i]),tmp,append=(i!=1),row.names=FALSE,col.names=(i==1))
}

# 'Cleanup' the original objects from memory (should be done by the gc if needed when loading the file
rm(list=ll)

# Read the file in the new object
dt<-fread(tmp)

# Remove the file
unlink(tmp)

显然比rbind方法慢,但是如果你有内存争用,这不会比要求系统交换内存页面慢。

当然,如果您的orignal对象最初是从文件加载的,那么在加载R之前,最好将文件连接到另一个最常用于处理文件的工具(cat,awk等)

答案 1 :(得分:3)

您可以在绑定数据表后删除它们,双重内存使用量是由包含副本的新数据帧引起的。

插图:

#create some data
nobs=10000
d1 <- d2 <- d3 <-  data.table(a=rnorm(nobs),b=rnorm(nobs))
dt <- rbindlist(list(d1,d2,d3))

然后我们可以查看每个对象的内存使用量source

sort( sapply(ls(),function(x){object.size(get(x))}))
  nobs     d1     d2     d3     dt 
    48 161232 161232 161232 481232 

如果内存使用量太大,单独的数据表和组合的数据表不能共存,我们可以(令人震惊,但恕我直言,这种情况保证它有少量的数据表,并且它易于阅读和理解) for循环和get创建我们的组合数据表并同时删除各个数据表:

mydts <- c("d1","d2","d3") #vector of datatable names

dt<- data.table() #empty datatable to bind objects to

for(d in mydts){
  dt <- rbind(dt, get(d))
  rm(list=d)
  gc() #garbage collection
}

答案 2 :(得分:2)

我猜<<-get可以帮助您解决此问题。

更新<<-不是必需的。

df1 <- data.frame(x1=1:4, x2=letters[1:4], stringsAsFactors=FALSE)
df2 <- df1
df3 <- df1

dt.lst <- c("df2", "df3")

for (i in dt.lst) {
  df1 <- rbind(df1, get(i))
  rm(list=i)
}

df1