R 记忆自定义函数并将其矢量化
我想知道如何在R中矢量化和记忆自定义函数 我的思维方式与R的运作方式不一致。所以,我很高兴 欢迎链接到好的阅读材料。例如,R地狱是一个很好的例子 资源,但这无助于找出R中的备忘录 更一般地说,您能否为R 记忆自定义函数并将其矢量化,r,vectorization,memoization,R,Vectorization,Memoization,我想知道如何在R中矢量化和记忆自定义函数 我的思维方式与R的运作方式不一致。所以,我很高兴 欢迎链接到好的阅读材料。例如,R地狱是一个很好的例子 资源,但这无助于找出R中的备忘录 更一般地说,您能否为备忘录 或者R.cache包 我找不到关于这个问题的任何其他讨论。搜索 r-bloggers.com上的“备忘录”或“备忘录”返回零结果。搜索 对于那些关键字,在不返回帮助 讨论。我通过电子邮件发送了邮件列表,但没有收到完整的邮件 回答 我不仅仅对记忆GC函数感兴趣,而且我知道 生物导体和各种封装
备忘录
或者R.cache
包
我找不到关于这个问题的任何其他讨论。搜索
r-bloggers.com上的“备忘录”或“备忘录”返回零结果。搜索
对于那些关键字,在不返回帮助
讨论。我通过电子邮件发送了邮件列表,但没有收到完整的邮件
回答
我不仅仅对记忆GC函数感兴趣,而且我知道
生物导体和各种封装
在那里可以买到
以下是我的数据:
seqs <- c("","G","C","CCC","T","","TTCCT","","C","CTC")
它的工作原理是:
> 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
我想把它记下来。然后,我想把它矢量化
显然,我使用回忆录
或
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
至少我知道了如何矢量化:
> 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
GCv GCv(序号)
G C CCC T TTCCT
NA 100.00000100.00000100.000000.00000 NA 40.00000 NA
C反恐委员会
100.00000 66.66667
相关stackoverflow帖子:
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
}
GC2虽然这不会让你在通话中进行记忆,但如果有相当多的重复,你可以使用因子使单个通话更快。例如,使用Joshua的GC2(尽管我必须删除fixed=T才能使其工作):
GC2是否有任何特殊原因使您忽略了nchar
和gregexpr
已经矢量化的事实?在我的系统(x86_64 linux gnu R 2.15.0)上,您的功能慢了约3倍。我正在这样测试速度:system.time(sapply(rep(seqs,1000),GC))
得到0.418秒<代码>系统时间(sapply(rep(seqs,1000),GC2))
得到1.401秒。@KamilSlowikowski这是因为您使用了错误的函数。Joshua对其进行了矢量化,因此您应该将其与GC2(rep(seqs,1000))
进行比较,在这种情况下,它确实快了~4倍。@KamilSlowikowski,尽管我认为他不是有意设置fixed=TRUE
。事实上,设置fixed=t
会导致所有[[1]]
元素都是-1
。乔舒亚,谢谢你的密码!现在我知道了如何从列表中的每个项目中提取一个元素,1*TRUE==1
和1*FALSE==0
。我现在觉得自己很傻,因为意识到nchar
和substr
可以处理项目的向量(“列表”),特别是因为帮助?nchar
明确说明了这一点。@joran:谢谢你指出这一点。这是我测试的一部分,因为?gregexpr
说使用fixed=TRUE
可以更快。。。但它不应该出现在我的答案中。这太棒了。非常感谢。回忆录将为我节省相对较少的时间。
> 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
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
}
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