J'ai une question triviale: je n'ai pas pu trouver une structure de données de dictionnaire dans R, donc j'ai utilisé la liste à la place (comme "mot" -> nombre) Donc, en ce moment, j'ai un problème pour obtenir la liste des clés. Quelqu'un le sait?
Réponses:
Oui, le list
type est une bonne approximation. Vous pouvez utiliser names()
sur votre liste pour définir et récupérer les 'clés':
> foo <- vector(mode="list", length=3)
> names(foo) <- c("tic", "tac", "toe")
> foo[[1]] <- 12; foo[[2]] <- 22; foo[[3]] <- 33
> foo
$tic
[1] 12
$tac
[1] 22
$toe
[1] 33
> names(foo)
[1] "tic" "tac" "toe"
>
environment
type est utilisé pour cela dans R, mais il est moins courant / moins connu.
Vous n'avez même pas besoin de listes si vos valeurs «numériques» sont toutes du même mode. Si je prends l'exemple de Dirk Eddelbuettel:
> foo <- c(12, 22, 33)
> names(foo) <- c("tic", "tac", "toe")
> foo
tic tac toe
12 22 33
> names(foo)
[1] "tic" "tac" "toe"
Les listes ne sont requises que si vos valeurs sont soit en mode mixte (par exemple, caractères et nombres), soit en vecteurs.
Pour les listes et les vecteurs, un élément individuel peut être sous-défini par son nom:
> foo["tac"]
tac
22
Ou pour une liste:
> foo[["tac"]]
[1] 22
Pour étendre un peu la réponse de Calimo, je présente quelques autres choses que vous pourriez trouver utiles lors de la création de ce quasi dictionnaires en R:
a) comment retourner toutes les VALEURS du dictionnaire:
>as.numeric(foo)
[1] 12 22 33
b) vérifier si le dictionnaire CONTIENT UNE CLÉ:
>'tic' %in% names(foo)
[1] TRUE
c) comment ajouter une nouvelle clé, une paire de valeurs au dictionnaire:
c (toto, tic2 = 44)
résultats:
tic tac toe tic2
12 22 33 44
d) comment remplir l'exigence du VRAI DICTIONNAIRE - que les clés NE PEUVENT PAS se répéter (CLÉS UNIQUES)? Vous devez combiner b) et c) et construire une fonction qui valide s'il existe une telle clé, et faire ce que vous voulez: par exemple, ne pas autoriser l'insertion, mettre à jour la valeur si la nouvelle est différente de l'ancienne, ou reconstruire d'une manière ou d'une autre la clé (par exemple ajoute un certain nombre pour qu'il soit unique)
e) comment SUPPRIMER la paire PAR CLÉ du dictionnaire:
foo <-foo [qui (foo! = foo [["tac"]])]
c(foo, tic2=NULL)
. Un travail autour?
La raison de l'utilisation des dictionnaires en premier lieu est la performance. Bien qu'il soit correct que vous puissiez utiliser des vecteurs et des listes nommés pour la tâche, le problème est qu'ils deviennent assez lents et gourmands en mémoire avec plus de données.
Pourtant, ce que beaucoup de gens ne savent pas, c'est que R a en effet une structure de données de dictionnaire intégrée: des environnements avec l'optionhash = TRUE
Consultez l'exemple suivant pour savoir comment le faire fonctionner:
# vectorize assign, get and exists for convenience
assign_hash <- Vectorize(assign, vectorize.args = c("x", "value"))
get_hash <- Vectorize(get, vectorize.args = "x")
exists_hash <- Vectorize(exists, vectorize.args = "x")
# keys and values
key<- c("tic", "tac", "toe")
value <- c(1, 22, 333)
# initialize hash
hash = new.env(hash = TRUE, parent = emptyenv(), size = 100L)
# assign values to keys
assign_hash(key, value, hash)
## tic tac toe
## 1 22 333
# get values for keys
get_hash(c("toe", "tic"), hash)
## toe tic
## 333 1
# alternatively:
mget(c("toe", "tic"), hash)
## $toe
## [1] 333
##
## $tic
## [1] 1
# show all keys
ls(hash)
## [1] "tac" "tic" "toe"
# show all keys with values
get_hash(ls(hash), hash)
## tac tic toe
## 22 1 333
# remove key-value pairs
rm(list = c("toe", "tic"), envir = hash)
get_hash(ls(hash), hash)
## tac
## 22
# check if keys are in hash
exists_hash(c("tac", "nothere"), hash)
## tac nothere
## TRUE FALSE
# for single keys this is also possible:
# show value for single key
hash[["tac"]]
## [1] 22
# create new key-value pair
hash[["test"]] <- 1234
get_hash(ls(hash), hash)
## tac test
## 22 1234
# update single value
hash[["test"]] <- 54321
get_hash(ls(hash), hash)
## tac test
## 22 54321
Edit : Sur la base de cette réponse, j'ai écrit un article de blog avec un peu plus de contexte: http://blog.ephorie.de/hash-me-if-you-can
Le hachage du package est maintenant disponible: https://cran.r-project.org/web/packages/hash/hash.pdf
Exemples
h <- hash( keys=letters, values=1:26 )
h <- hash( letters, 1:26 )
h$a
# [1] 1
h$foo <- "bar"
h[ "foo" ]
# <hash> containing 1 key-value pair(s).
# foo : bar
h[[ "foo" ]]
# [1] "bar"
Variation plus courte de la réponse de Dirk:
# Create a Color Palette Dictionary
> color <- c('navy.blue', 'gold', 'dark.gray')
> hex <- c('#336A91', '#F3C117', '#7F7F7F')
> # Create List
> color_palette <- as.list(hex)
> # Name List Items
> names(color_palette) <- color
>
> color_palette
$navy.blue
[1] "#336A91"
$gold
[1] "#F3C117"
$dark.gray
[1] "#7F7F7F"
Je vais juste commenter que vous pouvez gagner beaucoup de temps table
lorsque vous essayez de "falsifier" un dictionnaire également, par exemple
> x <- c("a","a","b","b","b","c")
> (t <- table(x))
x
a b c
2 3 1
> names(t)
[1] "a" "b" "c"
> o <- order(as.numeric(t))
> names(t[o])
[1] "c" "a" "b"
etc.
as.numeric()
soit nécessaire. Le tableau est déjà numérique. Vous pouvez obtenir le même résultat avecnames(t[order(t)])