recodificar - tablas en r
Trabajando con diccionarios/listas en R (8)
Tengo una pregunta trivial: no pude encontrar una estructura de datos de diccionario en R, así que utilicé la lista en su lugar (como "palabra" -> número) Entonces, ahora mismo tengo un problema sobre cómo obtener la lista de claves. ¿Cualquiera sabe?
El hash del paquete ya 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"
Es posible que desee ver el package hash
en CRAN.
La razón para usar diccionarios en primer lugar es el rendimiento. Aunque es correcto que puede usar vectores con nombre y listas para la tarea, el problema es que se están volviendo bastante lentos y la memoria está hambrienta de 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
Consulte el siguiente ejemplo para saber cómo hacer que funcione:
# 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
Me limitaré a comentar que también se puede sacar mucho provecho de la table
cuando se trata de "falsificar" un diccionario, por ej.
> 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.
Ni siquiera necesita listas si sus valores de "número" 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.
Para ambas listas y vectores, un elemento individual puede ser subconjunto por nombre:
> foo["tac"]
tac
22
O para una lista:
> foo[["tac"]]
[1] 22
Para ampliar un poco la respuesta de Calimo, presento algunas cosas más que pueden serle útiles al crear este cuasi dictionaris en R:
a) cómo devolver todos los VALORES del diccionario:
>as.numeric(foo)
[1] 12 22 33
b) verificar si el diccionario CONTIENE CLAVE:
>''tic'' %in% names(foo)
[1] TRUE
c) cómo agregar la NUEVA clave, valor piar al diccionario:
c (foo, tic2 = 44)
resultados:
tic tac toe tic2
12 22 33 44
d) ¿cómo cumplir con el requisito de DICCIONARIO REAL - que las teclas NO PUEDEN repetir (UNIQU KEYS)? Necesita combinar b) yc) y función de compilación que valida si hay tal clave, y haga lo que desee: por ejemplo, no permita la inserción, actualice el valor si el nuevo difiere del anterior, o reconstruya de alguna manera la clave (p. Ej. le agrega un número así que es único)
e) cómo BORRAR el par BY KEY del diccionario:
foo <-foo [que (foo! = foo [["tac"]])]
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"
Sí, el tipo de list
es una buena aproximación. Puede usar names()
en su lista para establecer y recuperar las ''claves'':
> 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"
>