0

对于一个范围,我想确定分布变化发生在哪里以及该值在哪里是最大值目前,我正在对范围内的每个值使用内核最大差异测试,并在该值之前和之后取 200 个值,然后提取 mmd 统计信息最大的位置。但这在 R 中计算的计算量非常大。请注意,我使用的是 kernlab 来计算 kmmd。我想知道是否有办法更快地做到这一点?或者如果您有任何建议。任何帮助,将不胜感激。

我的代码是:

    cvg<-seq(1,2000)
    cvg<-cvg^3-2*cvg^2+5*cvg
    myRange<-seq(400:(length(cvg)-400))
    kernel<-"splinedot"
    cvg[201:(length(cvg)-200)]->cvg
    myRange<-seq(400:(length(cvg)-400))
    lapply(myRange, function(x) mmdstats(kmmd((as.matrix(cvg[(x+1):(x+400)])), (as.matrix(cvg[(x+801):(x+1200)])), kernel=kernel)))->kmm.ls
    as.data.frame(as.matrix(kmm.ls))->kmm.ls
    lapply(kmm.ls, function(x) which.max(mmdstats(x)))->store.max
4

1 回答 1

1

我声明我不是该主题的专家,kernlab因此我无法判断您分析的正确性或改进您的代码。但是,我可以建议您将lapply调用转换为并行版本,例如sfLapply, parLapply, mclapply future_lapplyecc。sfLapply在这里,我从包中发布了一个示例snowfall(这真的很简单 imo):

#your original lapply call took 500 seconds on my PC
system.time(kmm.ls <- lapply(myRange, function(x) mmdstats(kmmd((as.matrix(cvg[(x+1): 
(x+400)])), (as.matrix(cvg[(x+801):(x+1200)])), kernel=kernel))))


library(kernlab)
library(snowfall)
sfInit(parallel=TRUE,cpus = parallel::detectCores()-1)
# Load the required packages inside the cluster
sfLibrary(kernlab)
#export all variable in all the cluster
sfExportAll()
# Run parallelized lapply with custom function  
#sfLapply took 22 second on my 48 cores PC
system.time(kmm.ls <- sfLapply(myRange, function(x) 
mmdstats(kmmd((as.matrix(cvg[(x+1):(x+400)])), (as.matrix(cvg[(x+801):(x+1200)])), 
kernel=kernel))))
#stop cluster
sfStop()

这是一个仅第一次lapply调用您的代码的示例,但同样的想法可以应用于第二次调用(当我尝试运行您的代码时,第二次lapply调用给我一个错误)

(函数(类,fdef,mtable)中的错误:无法为签名“列表”找到函数“mmdstats”的继承方法</p>

这似乎不是一个严重错误,但正如我所说,我不准备建议如何修复它。

于 2021-04-20T09:25:00.860 回答