我想知道如何在R中矢量化和记忆自定义函数。似乎 我的思维方式与R的运作方式不一致。所以,我很高兴 欢迎任何链接到良好的阅读材料。例如,R inferno很不错 资源,但它没有帮助在R中找出记忆。
更一般地说,您能否为memoise
提供相关的使用示例
或R.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
或
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帖子:
答案 0 :(得分:2)
虽然这不会让您通过电话进行记忆,但是如果有相当多的重复,您可以使用因子来使个别电话更快。例如,使用Joshua的GC2(虽然我必须删除fixed = T才能使它工作):
GC2 <- function(s) {
if(!is.character(s)) stop("'s' must be character")
n <- nchar(s)
m <- gregexpr('[GCSgcs]', s)
len <- sapply(m, length)
neg <- sapply(m, "[[", 1)
len <- len*(neg > 0)
100.0 * len/n
}
可以轻松定义一个包装器,如:
GC3 <- function(s) {
x <- factor(s)
GC2(levels(x))[x]
}
system.time(GC2(rep(seqs, 50000)))
# user system elapsed
# 8.97 0.00 8.99
system.time(GC3(rep(seqs, 50000)))
# user system elapsed
# 0.06 0.00 0.06
答案 1 :(得分:1)
这并没有明确回答你的问题,但这个功能比你的快4倍。
GC2 <- function(s) {
if(!is.character(s)) stop("'s' must be character")
n <- nchar(s)
m <- gregexpr('[GCSgcs]', s)
len <- sapply(m, length)
neg <- sapply(m, "[[", 1)
len <- len*(neg > 0)
len/n
}