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

滞后变量的sapply内存错误

  •  1
  • user6883405  · 技术社区  · 6 年前

    编辑:例如假数据

    df = matrix(runif(50*507), nrow = 50, ncol = 507)
    df = data.frame(df)
    df[,1] = seq(as.Date("2017/1/1"), as.Date("2017/2/19"), "days")
    names(df) = paste0("var", 1:507)
    names(df)[505:507] = c("mktrf", "smb", "hml")
    names(df)[1] = "Date"
    

    所有dep变量

    x = df[,505:507]
    

    所有indep var

    y <- df[,2:504]
    

    我有一个名为shift的函数,我想应用于df的每一列。函数滞后于变量。函数如下所示,并将指定列移动指定的数字。

    shift<-function(x,shift_by){
      stopifnot(is.numeric(shift_by))
      stopifnot(is.numeric(x))
    
      if (length(shift_by)>1)
        return(sapply(shift_by,shift, x=x))
    
      out<-NULL
      abs_shift_by=abs(shift_by)
      if (shift_by > 0 )
        out<-c(tail(x,-abs_shift_by),rep(NA,abs_shift_by))
      else if (shift_by < 0 )
        out<-c(rep(NA,abs_shift_by), head(x,-abs_shift_by))
      else 
        out<-x
      out
    }
    

    当我像这样使用sapply函数时,其中y是一个由我想要滞后的时间序列变量组成的数据帧:

    y_lag <- sapply(y,shift,-1 )
    

    我得到以下错误:

    Error: cannot allocate vector of size 54.2 Mb
    In addition: Warning messages:
    1: In unlist(x, recursive = FALSE) :
      Reached total allocation of 8072Mb: see help(memory.size)
    2: In unlist(x, recursive = FALSE) :
      Reached total allocation of 8072Mb: see help(memory.size)
    3: In unlist(x, recursive = FALSE) :
      Reached total allocation of 8072Mb: see help(memory.size)
    4: In unlist(x, recursive = FALSE) :
      Reached total allocation of 8072Mb: see help(memory.size)
    5: In unlist(x, recursive = FALSE) :
      Reached total allocation of 8072Mb: see help(memory.size)
    6: In unlist(x, recursive = FALSE) :
      Reached total allocation of 8072Mb: see help(memory.size)
    

    我的问题是:在仍然使用lm包的情况下,是否可以使用不同的方法延迟列的每个元素?或者如何解决我的内存问题?我不能用别的电脑。

    2 回复  |  直到 6 年前
        1
  •  0
  •   user6883405    6 年前

    我能够使用lagpad函数使其工作,该函数在另一个问题中描述:

    lagpad <- function(x, k=1) {
      i<-is.vector(x)
      if(is.vector(x)) x<-matrix(x) else x<-matrix(x,nrow(x))
      if(k>0) {
        x <- rbind(matrix(rep(NA, k*ncol(x)),ncol=ncol(x)), matrix(x[1:(nrow(x)-k),], ncol=ncol(x)))
      }
      else {
        x <- rbind(matrix(x[(-k+1):(nrow(x)),], ncol=ncol(x)),matrix(rep(NA, -k*ncol(x)),ncol=ncol(x)))
      }
      if(i) x[1:length(x)] else x
    }
    

    这本质上就是r2evans所描述的,改变了整个df。

        2
  •  0
  •   MKR    6 年前

    有几个选项可以避免使用 sapply 在这种情况下。一种选择是使用 mutate_all

    library(dplyr)
    
    y_lag <- mutate_all(y, shift, shift_by = -1)
    
    tail(y_lag)
    #var2      var3      var4      var5       var6      var7      var8       var9      var10
    #45 0.26817677 0.9664805 0.2849259 0.6375189 0.20889115 0.1530204 0.6500325 0.78397715 0.32936124
    # many more rows to follow