首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >R中缓存/回传/散列的选项

R中缓存/回传/散列的选项
EN

Stack Overflow用户
提问于 2011-08-31 19:41:26
回答 3查看 12.1K关注 0票数 73

我试图找到一种简单的方法,在R中使用类似Perl的散列函数(本质上是缓存),因为我打算同时进行Perl风格的散列和编写我自己的计算回忆录。然而,其他人已经击败了我,并有回忆录的包裹。我挖掘得越多,我发现的就越多,例如memoiseR.cache,但差异并不明显。此外,除了使用hash包之外,还不清楚如何获得Perl风格的散列(或Python风格的字典)并编写自己的回忆录,这似乎并不是这两个回忆录包的基础。

由于我找不到关于CRAN或其他地方的信息来区分这些选项,也许这应该是一个社区wiki问题:在R中回忆录和缓存的选项是什么,它们有什么不同?

作为比较的基础,下面是我找到的选项列表。而且,在我看来,这都取决于散列,所以我也会注意到散列选项。密钥/值存储在某种程度上是相关的,但是对于DB系统(例如BerkeleyDB、Redis、MemcacheDB和其他几十个),会打开大量的蠕虫。

看起来这些选项是:

散列

  • 消化 -为任意R对象提供散列。

追忆

  • 回忆录 --一个非常简单的函数回忆录工具。
  • R.cache --提供了更多的回忆录功能,尽管其中一些功能似乎缺乏示例。

缓存

  • 哈希 -提供类似于Perl的散列和Python的缓存功能。

密钥/值存储

这些是R对象外部存储的基本选项。

  • 施塔什
  • 文件散列

检查点

  • 传道人 --这看起来更像检查点
  • CodeDepends -一个OmegaHat项目,它支持cacher并提供一些有用的功能。
  • DMTCP (不是一个R包)--似乎支持一堆语言和最近,一名开发人员请求协助测试R中的DMTCP检查点。中的检查点。

其他

  • 基本R支持:命名向量和列表,数据帧的行和列名称,以及环境中的项名。在我看来,使用一个列表似乎有点杂乱无章。(也有pairlist,但这是不可取的。)
  • data.table包支持快速查找数据表中的元素。

用例

虽然我最感兴趣的是了解这些选项,但我有两个基本的用例:

  1. 缓存:字符串的简单计数。注意:这不是NLP,而是一般的使用,所以NLP库是过火的;表是不够的,因为我不想等到整个字符串被加载到内存中。Perl风格的散列在正确的实用程序级别上.
  2. 令人难忘的计算。

这些真的出现了,因为我是深入研究一些血样代码的剖析,我真的很想数一下简单的字符串,看看我是否可以通过回忆录加速一些计算。能够散列输入值,即使我没有回忆录,也可以让我看看回忆录是否有帮助。

注1:可复制性研究的CRAN任务观列出了几个包(cacherR.cache),但没有详细说明使用选项。

注2:为了帮助其他寻找相关代码的人,这里有一些作者或包的注释。有些作者这么说。:)

  • Dirk:digest -许多其他软件包都依赖于此。
  • 罗杰·彭:cacherfilehashstashR --它们以不同的方式解决不同的问题;更多的软件包见罗杰遗址
  • Christopher:hash --似乎是一个有用的包,但是不幸的是,到ODG的链接被关闭了。
  • 亨里克·本特松:R.cache & Hadley Wickham:memoise --目前还不清楚什么时候应该选择一个包而不是另一个包。

注3:有些人使用回忆录/回忆录,另一些人使用回忆录/回忆录。如果你到处找的话就写个便条。亨里克使用"z“,哈德利使用"s”。

EN

回答 3

Stack Overflow用户

发布于 2014-07-31 10:52:46

我对memoise并不满意,因为它给我尝试过的包的某些函数带来了“太深的递归”问题。和R.cache在一起,我运气更好。下面是我从R.cache文档中改编的更多带注释的代码。代码显示了执行缓存的不同选项:

代码语言:javascript
运行
复制
# Workaround to avoid question when loading R.cache library
dir.create(path="~/.Rcache", showWarnings=F) 
library("R.cache")
setCacheRootPath(path="./.Rcache") # Create .Rcache at current working dir
# In case we need the cache path, but not used in this example.
cache.root = getCacheRootPath() 
simulate <- function(mean, sd) {
    # 1. Try to load cached data, if already generated
    key <- list(mean, sd)
    data <- loadCache(key)
    if (!is.null(data)) {
        cat("Loaded cached data\n")
        return(data);
    }
    # 2. If not available, generate it.
    cat("Generating data from scratch...")
    data <- rnorm(1000, mean=mean, sd=sd)
    Sys.sleep(1) # Emulate slow algorithm
    cat("ok\n")
    saveCache(data, key=key, comment="simulate()")
    data;
}
data <- simulate(2.3, 3.0)
data <- simulate(2.3, 3.5)
a = 2.3
b = 3.0
data <- simulate(a, b) # Will load cached data, params are checked by value
# Clean up
file.remove(findCache(key=list(2.3,3.0)))
file.remove(findCache(key=list(2.3,3.5)))

simulate2 <- function(mean, sd) {
    data <- rnorm(1000, mean=mean, sd=sd)
    Sys.sleep(1) # Emulate slow algorithm
    cat("Done generating data from scratch\n")
    data;
}
# Easy step to memoize a function
# aslo possible to resassign function name.
This would work with any functions from external packages. 
mzs <- addMemoization(simulate2)

data <- mzs(2.3, 3.0)
data <- mzs(2.3, 3.5)
data <- mzs(2.3, 3.0) # Will load cached data
# aslo possible to resassign function name.
# but different memoizations of the same 
# function will return the same cache result
# if input params are the same
simulate2 <- addMemoization(simulate2)
data <- simulate2(2.3, 3.0)

# If the expression being evaluated depends on
# "input" objects, then these must be be specified
# explicitly as "key" objects.
for (ii in 1:2) {
    for (kk in 1:3) {
        cat(sprintf("Iteration #%d:\n", kk))
        res <- evalWithMemoization({
            cat("Evaluating expression...")
            a <- kk
            Sys.sleep(1)
            cat("done\n")
            a
        }, key=list(kk=kk))
        # expressions inside 'res' are skipped on the repeated run
        print(res)
        # Sanity checks
        stopifnot(a == kk)
        # Clean up
        rm(a)
    } # for (kk ...)
} # for (ii ...)
票数 11
EN

Stack Overflow用户

发布于 2011-08-31 21:31:06

对于字符串的简单计数(而不使用table或类似的),多集数据结构似乎很适合。可以使用environment对象来模拟这种情况。

代码语言:javascript
运行
复制
# Define the insert function for a multiset
msetInsert <- function(mset, s) {
    if (exists(s, mset, inherits=FALSE)) {
        mset[[s]] <- mset[[s]] + 1L
    } else {
        mset[[s]] <- 1L 
    }
}

# First we generate a bunch of strings
n <- 1e5L  # Total number of strings
nus <- 1e3L  # Number of unique strings
ustrs <- paste("Str", seq_len(nus))

set.seed(42)
strs <- sample(ustrs, n, replace=TRUE)


# Now we use an environment as our multiset    
mset <- new.env(TRUE, emptyenv()) # Ensure hashing is enabled

# ...and insert the strings one by one...
for (s in strs) {
    msetInsert(mset, s)
}

# Now we should have nus unique strings in the multiset    
identical(nus, length(mset))

# And the names should be correct
identical(sort(ustrs), sort(names(as.list(mset))))

# ...And an example of getting the count for a specific string
mset[["Str 3"]] # "Str 3" instance count (97)
票数 9
EN

Stack Overflow用户

发布于 2017-07-04 00:47:55

@biocyperman溶液有关。R.cache有一个包装功能,以避免缓存的加载、保存和评估。请参阅修改后的函数:

R.cache为加载、评估、保存提供了一个包装器。您可以这样简化代码:

代码语言:javascript
运行
复制
simulate <- function(mean, sd) {
key <- list(mean, sd)
data <- evalWithMemoization(key = key, expr = {
    cat("Generating data from scratch...")
    data <- rnorm(1000, mean=mean, sd=sd)
    Sys.sleep(1) # Emulate slow algorithm
    cat("ok\n")
    data})
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7262485

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档