我想知道如何在 R 中对自定义函数进行矢量化和记忆。看来我的思维方式与 R 的操作方式不一致。所以,我很高兴欢迎任何指向优秀阅读材料的链接。例如,R inferno 是一个很好的资源,但它并没有帮助弄清楚 R 中的记忆。
更一般地说,您能否提供memoise
orR.cache
包的相关使用示例?
我还没有找到关于这个主题的任何其他讨论。在 r-bloggers.com 上搜索“memoise”或“memoize”返回零结果。在http://r-project.markmail.org/搜索这些关键字不会返回有用的讨论。我通过电子邮件发送了邮件列表,但没有收到完整的答复。
我不仅对记忆 GC 功能感兴趣,而且我知道 Bioconductor 和那里可用的各种软件包。
这是我的数据:
seqs <- c("","G","C","CCC","T","","TTCCT","","C","CTC")
缺少一些序列,因此它们是空白的""
。
我有一个计算 GC 内容的函数:
> GC <- function(s) {
if (!is.character(s)) return(NA)
n <- nchar(s)
if (n == 0) return(NA)
m <- gregexpr('[GCSgcs]', s)[[1]]
if (m[1] < 1) return(0)
return(100.0 * length(m) / n)
}
有用:
> GC('')
[1] NA
> GC('G')
[1] 100
> GC('GAG')
[1] 66.66667
> sapply(seqs, GC)
G C CCC T TTCCT
NA 100.00000 100.00000 100.00000 0.00000 NA 40.00000 NA
C CTC
100.00000 66.66667
我想记住它。然后,我想对其进行矢量化。
显然,我必须对使用memoise
or
R.cache
R 包有错误的心态:
> system.time(dummy <- sapply(rep(seqs,100), GC))
user system elapsed
0.044 0.000 0.054
>
> library(memoise)
> GCm1 <- memoise(GC)
> system.time(dummy <- sapply(rep(seqs,100), GCm1))
user system elapsed
0.164 0.000 0.173
>
> library(R.cache)
> GCm2 <- addMemoization(GC)
> system.time(dummy <- sapply(rep(seqs,100), GCm2))
user system elapsed
10.601 0.252 10.926
请注意,记忆函数要慢几个数量级。
我尝试了这个hash
包,但事情似乎在幕后发生,我不明白输出。该序列C
的值应为100
,而不是NULL
。
请注意,使用has.key(s, cache)
而不是exists(s, cache)
导致相同的输出。此外,使用cache[s] <<- result
而不是
cache[[s]] <<- result
导致相同的输出。
> cache <- hash()
> GCc <- function(s) {
if (!is.character(s) || nchar(s) == 0) {
return(NA)
}
if(exists(s, cache)) {
return(cache[[s]])
}
result <- GC(s)
cache[[s]] <<- result
return(result)
}
> sapply(seqs,GCc)
[[1]]
[1] NA
$G
[1] 100
$C
NULL
$CCC
[1] 100
$T
NULL
[[6]]
[1] NA
$TTCCT
[1] 40
[[8]]
[1] NA
$C
NULL
$CTC
[1] 66.66667
至少我想出了如何矢量化:
> GCv <- Vectorize(GC)
> GCv(seqs)
G C CCC T TTCCT
NA 100.00000 100.00000 100.00000 0.00000 NA 40.00000 NA
C CTC
100.00000 66.66667
相关的stackoverflow帖子: