0

我已经尝试了很多东西,但在矢量化这段代码时遇到了很多麻烦。我已经设法找到了一种使用 lapply 执行此操作的方法,但它比下面的代码稍慢。请注意,数据按行数增加的err位置排序。err

mySlowFunction <- function(data, vectorizedFunc){
  #data is a data.frame
  #vectorizedFunc is a function
  n <- d <- array(0, dim = c(nrow(data),1))
  for (i in 1:nrow(data)){
      err.i <- data$err[i]
      wt <- vectorizedFunc(data$X[i:nrow(data)] + err.i)
      n[i] <- sum(data$Y[i:nrow(data)] / wt)
      d[i] <- sum(1 / wt)
  }
  data$N.wt <- n
  data$D.wt <- d
  data
}

data <- data.frame(X = rnorm(10000), Y = rnorm(10000), err = rnorm(10000))
data <- data[order(data$err),]
system.time(mySlowFunction(data, exp))

我稍慢的 lapply 版本:

myEvenSlowerFunction <- function(data, vectorizedFunc){
  #data is a data.frame
  res <- unlist(lapply(data$err, function(x) {
    idx <- which(data$err >= x)
    wt <- vectorizedFunc(data$X[idx] + x)
    c(sum(data$Y[idx] / wt), sum(1 / wt))
  }))
  idx <- seq(1,length(res) - 1,by=2)
  data$N.wt <- res[idx]
  data$D.wt <- res[idx + 1]
  data
}

谢谢!

4

2 回答 2

0

我认为你的解决方案可能和它一样好。您已经对内部函数调用进行了矢量化处理,进一步调整似乎没有任何重大收获。恰恰相反,事实上。

这是一个完全矢量化的“解决方案”,outer用于生成wt变量。这比您的代码慢,主要是因为 1)它需要在内存中创建一个 NxN 矩阵,其中 N = nrow(data); 2)这些矩阵元素的一半是不必要的。把它放在那里,看看其他人是否可以改进它。

vecf <- function(data, vectorizedFunc)
{
    wt <- outer(data$e, data$X, "+")
    wt[lower.tri(wt)] <- NA
    wt <- vectorizedFunc(wt)
    data$N.wt <- rowSums(rep(data$Y, each=nrow(data))/wt, na.rm=TRUE)
    data$D.wt <- rowSums(1/wt, na.rm=TRUE)
    data
}
于 2013-11-06T07:45:12.040 回答
0

已编辑

等待。不是 R 只是使用单线程吗?据我所知,向量化是用于并行计算的……如果您愿意使用“展开”,这将大大减少计算时间。

myFunction <- function(data, vectorizedFunc){
  #data is a data.frame
  #vectorizedFunc is a function
  len=nrow(data)        ## if you are going to compute something over and over,  
                        ## justsave          them
  n = d = numeric(len)
  for (i in 1:len){
    err.i <- data$err[i]
    temp=data$X[i:len]   ## changed
    wt <- vectorizedFunc( temp+ err.i)
    n[i] <- sum(temp / wt)
    d[i] <- sum(1 / wt)
  }
  data$N.wt <- n
  data$D.wt <- d
  data
}

system.time(myFunction(data, exp))
#   user  system elapsed 
#   5.01    0.00    5.04 

#while your function gives

#   user  system elapsed 
#   6.15    0.02    6.20 
于 2013-11-06T06:48:49.533 回答