73 votes

Options de mise en cache / mémorisation / hachage dans R

Je suis en train d'essayer de trouver un moyen simple d'utiliser quelque chose comme Perl fonctions de hachage dans R (essentiellement la mise en cache), que j'avais l'intention de faire les deux Perl-style de hachage et d'écrire ma propre memoisation de calculs. Cependant, d'autres ont me battre pour le punch et avons des forfaits pour memoisation. Plus je creuse, plus je trouve, par exemple,memoise et R.cache, mais les différences ne sont pas facilement clair. En outre, il n'est pas clair comment on peut obtenir Perl-style de hachages (ou Python-style dictionnaires) et écrire son propre memoization, autres que l'usage de l' hash package, qui ne semble pas sous-tendent les deux memoization paquets.

Depuis que je peux trouver aucune information sur CRAN ou d'ailleurs de distinguer entre les options, peut-être cela devrait être une communauté wiki question DONC: Quelles sont les options pour memoization et la mise en cache dans R, et quelles sont leurs différences?


A titre de comparaison, voici une liste des options que j'ai trouvé. Aussi, il me semble que tout dépend de hachage, donc je vais noter le hachage et des options. Clé/valeur de stockage est liée en quelque sorte, mais ouvre une énorme boîte de pandore concernant systèmes DB (par exemple, BerkeleyDB, Redis, MemcacheDB et des dizaines d'autres).

On dirait les options sont les suivantes:

Le hachage

  • digest - offre de hachage pour arbitraire de R objets.

Memoization

  • memoise - un outil très simple pour memoization de fonctions.
  • R. cache - offre plus de fonctionnalités pour memoization, mais il semble que certaines des fonctions de l'absence d'exemples.

La mise en cache

  • hachage - Fournit des fonctionnalités de mise en cache semblable à Perl de hachages et les dictionnaires Python.

Clé/valeur de stockage

Ce sont des options de base pour le stockage externe de R objets.

Les points de contrôle

D'autres

  • De la Base de R prend en charge: nom des vecteurs et des listes, en ligne et en colonne les noms des trames de données, et les noms d'objets dans les environnements. Il me semble que l'utilisation d'une liste est un peu de bidouille. (Il y a aussi pairlist, mais il est obsolète.)
  • Les données.tableau package prend en charge rapide des recherches d'éléments dans un tableau de données.

Cas d'utilisation

Même si je suis surtout intéressé à en connaître les options, j'ai deux types d'utilisation de base qui se posent:

  1. La mise en cache: un Simple comptage des chaînes de caractères. [Note: Ce n'est pas pour la PNL, mais en général les utiliser, de sorte que la PNL bibliothèques sont exagéré; les tables sont insuffisants, car je préfère ne pas attendre jusqu'à ce que l'ensemble des chaînes sont chargés en mémoire. Perl-style hachages sont au bon niveau d'utilité.]
  2. Memoization de monstrueux calculs.

Ces vraiment surviennent parce que je suis à creuser pour le profilage de certains slooooow code et j'aimerais vraiment compter de simples chaînes et voir si je peux accélérer certains calculs via memoization. Être en mesure de hachage les valeurs d'entrée, même si je n'ai pas memoize, permettez-moi de voir si memoization peut vous aider.


Note 1: Le CRAN Tâche de Vue sur Reproductible de Recherche de listes d'un couple de paquets (cacher et R.cache), mais il n'y a pas d'élaboration sur les options d'utilisation.

Note 2: À l'aide d'autres personnes à la recherche de code, voici quelques notes sur certains des auteurs ou des paquets. Certains auteurs utilisent. :)

  • Dirk Eddelbuettel: digest - beaucoup d'autres paquets dépendent de cela.
  • Roger Peng: cacher, filehash, stashR - elles s'adressent à différents problèmes de différentes façons, voir Roger du site pour plus de paquets.
  • Christopher Brown: hash - Semble être un bon paquet, mais les liens vers les ODG sont en baisse, malheureusement.
  • Henrik Bengtsson: R.cache & Hadley Wickham: memoise -- il n'est pas encore clair quand à préférer l'une sur l'autre.

Note 3: Certaines personnes utilisent des memoise/memoisation d'autres utilisent memoize/memoization. Juste une remarque, si vous êtes à la recherche autour de. Henrik utilise des "z" et Hadley utilise des "s".

11voto

biocyberman Points 311

Je n'ai pas eu de chance avec memoise parce que cela donnait un problème à too deep recursive à une fonction d'un package avec lequel j'avais essayé. Avec R.cache j'ai eu plus de chance. Ce qui suit est un code plus annoté que j’ai adapté à partir de la documentation R.cache . Le code montre différentes options pour la mise en cache.

 # 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 ...)
 

9voto

Tommy Points 16323

Pour un comptage simple des chaînes (sans utiliser table ou similaire), une structure de données multiset semble être un bon ajustement. L'objet environment peut être utilisé pour émuler cela.

 # 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)
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X