Tengo una pregunta trivial: no pude encontrar una estructura de datos de diccionario en R, así que usé lista en su lugar (como "palabra" -> número) Entonces, ahora mismo tengo un problema sobre cómo obtener la lista de claves. ¿Cualquiera sabe?
93
environment
tipo se usa para eso en R, pero es menos común / menos conocido.Ni siquiera necesita listas si sus valores "numéricos" son todos del mismo modo. Si tomo el ejemplo 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"
Las listas solo son necesarias si sus valores son de modo mixto (por ejemplo, caracteres y números) o vectores.
Tanto para listas como para vectores, un elemento individual se puede subdividir por nombre:
> foo["tac"] tac 22
O para una lista:
> foo[["tac"]] [1] 22
fuente
c(12,22,33)
de esta estructura R de estilo diccionario foo?unlist(lapply(FUN=function(a){foo[[a]]},X = 1:length(foo)))
es muy inconveniente. ¿Alguna función lista para esto? Movido la pregunta aquíPara extender un poco la respuesta de Calimo, presento algunas cosas más que pueden resultarle útiles al crear estos cuasi diccionarios en R:
a) cómo devolver todos los VALORES del diccionario:
>as.numeric(foo) [1] 12 22 33
b) compruebe si el diccionario CONTIENE CLAVE:
>'tic' %in% names(foo) [1] TRUE
c) cómo AÑADIR NUEVA clave, par de valores al diccionario:
resultados:
tic tac toe tic2 12 22 33 44
d) ¿Cómo cumplir con el requisito del DICCIONARIO REAL - que las teclas NO PUEDEN repetirse (LLAVES ÚNICAS)? Necesita combinar b) yc) y construir la función que valida si existe dicha clave, y hacer lo que quiera: por ejemplo, no permitir la inserción, actualizar el valor si el nuevo difiere del anterior o reconstruir de alguna manera la clave (por ejemplo, agrega un número para que sea único)
e) cómo BORRAR par POR CLAVE del diccionario:
fuente
c(foo, tic2=NULL)
. ¿Alguna solución?La razón para usar diccionarios en primer lugar es el rendimiento. Aunque es correcto que se puedan utilizar listas y vectores con nombre para la tarea, el problema es que se están volviendo bastante lentos y con mucha memoria con más datos.
Sin embargo, lo que mucha gente no sabe es que R tiene una estructura de datos de diccionario incorporada: entornos con la opción
hash = TRUE
Vea el siguiente ejemplo para saber cómo hacerlo funcionar:
# 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
Editar : sobre la base de esta respuesta, escribí una publicación de blog con más contexto: http://blog.ephorie.de/hash-me-if-you-can
fuente
El hash del paquete ahora está disponible: https://cran.r-project.org/web/packages/hash/hash.pdf
Ejemplos
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"
fuente
Variación más corta de la respuesta 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"
fuente
Solo comentaré que puedes aprovechar mucho
table
cuando intentas "falsificar" un diccionario también, por ejemplo> 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.
fuente
as.numeric()
sea necesario. La tabla ya es numérica. Puede obtener el mismo resultado connames(t[order(t)])