R中的下采样矩阵?

时间:2016-05-20 17:54:48

标签: r performance resampling

我的问题是关于如何提高函数的性能,从矩阵的列中进行下采样而无需替换(也就是"稀疏"矩阵...我知道已经提到了这个{{ 3}},但我找不到一个明确的答案:a)做我需要的; b)快速完成)。

这是我的功能:

downsampled <- function(data,samplerate=0.8) {
    data.test <- apply(data,2,function(q) {
    names(q) <- rownames(data)
    samplepool <- character()
    for (i in names(q)) {
      samplepool <- append(samplepool,rep(i,times=q[i]))  
    }
    sampled <- sample(samplepool,size=samplerate*length(samplepool),replace = F)
    tab <- table(sampled)
    mat <- match(names(tab),names(q))
    toret=numeric(length <- length(q))
    names(toret) <- names(q)
    toret[mat] <- tab
    return(toret)
  })
return(data.test)
}

我需要对数百万条目的矩阵进行下采样。我发现这很慢(这里我使用1000x1000矩阵,比我的典型数据大小小20-100倍):

mat <- matrix(sample(0:40,1000*1000,replace=T),ncol=1000,nrow=1000)
colnames(mat) <- paste0("C",1:1000)
rownames(mat) <- paste0("R",1:1000)
system.time(matd <- downsampled(mat,0.8))

##  user  system elapsed 
## 69.322  21.791  92.512 

有没有更快/更简单的方法来执行此操作,我还没有想到?

2 个答案:

答案 0 :(得分:0)

节省的一个来源是删除使用<input type="hidden" name="captcha-id" value="${cookie.captchaId.value}">附加samplepool的for循环。这是一个可重复的例子:

rep

在你的功能中,这将是

myRows <- 1:5
names(myRows) <- letters[1:5]
# get the repeated values for sampling
samplepool <- rep(names(myRows), myRows)

答案 1 :(得分:0)

我认为你可以大大加快这个速度。如果我理解你正在尝试做什么,你想要对矩阵的每个单元格进行下采样,这样如果samplerate = 0.5和矩阵的单元格是mat[i,j] = 5,那么你想要采样5件事情,每件事物有0.5次被采样的机会。

为了加快速度,而不是在矩阵的列上执行所有这些操作,您可以循环遍历矩阵的每个单元格,使用{{1}从该单元格中绘制 n 内容(例如,如果runif,您可以生成0到1之间的5个随机数,然后将mat[i,j] = 5的值相加,最后将事物数添加到新矩阵中。我认为这有效地实现了相同的下采样方案,但效率更高(在运行时间和代码行方面)。

< samplerate

使用示例1000 X 1000矩阵,我提供的新功能运行速度提高了约6倍。