代码之家  ›  专栏  ›  技术社区  ›  Ben

R将对象放入列表中,同时避免复制(即保持低内存要求)

  •  1
  • Ben  · 技术社区  · 7 年前

    我有一个函数:1)加载一些大型CSV文件;2)处理这些数据集;3)将它们放入列表并返回列表对象。看起来像这样

    library(data.table)
    
    load_data <- function(){
    
      # Load the data
      foo <- data.table(iris)  # really this:  foo <- fread("foo.csv")
      bar <- data.table(mtcars)  # really this:  bar <- fread("bar.csv")
    
      # Clean the data
      foo[, Foo := mean(Sepal.Length) + median(bar$carb)]
      # ... lots of code here
    
      # Put datasets into a list
      datasets <- list(foo = foo[], bar = bar[])
    
      # Return result
      return(datasets)
    }
    

    我担心的是,当我构建list对象时,我会加倍所需的内存,因为我基本上是在为每个数据集创建一个副本。

    1. 我的假设正确吗?
    2. 如果我的假设是正确的,是否可以在不复制对象的情况下将对象分配给列表?一种可能的解决方案是将这些对象从getgo加载到列表中 (e.g. datasets <- list(foo = fread("foo.csv"), bar = fread("bar.csv"))) 但这是不可取的,因为代码变得冗长和混乱,经常使用 datasets$foo datasets$bar .
    1 回复  |  直到 7 年前
        1
  •  3
  •   Calum You    7 年前

    你可能想查一下哈德利的资料 memory usage in R 这里,但作为一个简单的说明:

    library(pryr)
    mem_used()
    #> 36.1 MB
    foo <- iris
    bar <- mtcars
    mem_used() # Loading the datasets into objects requires some memory
    #> 36.4 MB
    foo["Foo"] <- mean(foo$Sepal.Length) + median(bar$carb)
    mem_used()
    #> 36.6 MB # Modifying requires some more memory
    foo_list <- list(foo)
    mem_used() # Adding to the list doesn't really (it's a few bytes)
    #> 36.6 MB
    

    于2018-08-03由 reprex package (第0.2.0版)。