Mam trywialne pytanie: nie mogłem znaleźć struktury danych słownika w R, więc zamiast tego użyłem listy (np. „Słowo” -> liczba). W tej chwili mam problem ze znalezieniem listy kluczy. Czy ktoś wie?
93
Tak, list
typ jest dobrym przybliżeniem. Możesz użyć names()
na swojej liście, aby ustawić i pobrać `` klucze '':
> 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
typ jest używany do tego w R, ale jest mniej powszechny / mniej znany.Nie potrzebujesz nawet list, jeśli wszystkie wartości „liczb” są w tym samym trybie. Jeśli wezmę przykład Dirka Eddelbuettela:
> foo <- c(12, 22, 33) > names(foo) <- c("tic", "tac", "toe") > foo tic tac toe 12 22 33 > names(foo) [1] "tic" "tac" "toe"
Listy są wymagane tylko wtedy, gdy wartości są albo w trybie mieszanym (na przykład znaki i cyfry), albo w wektorach.
Zarówno w przypadku list, jak i wektorów, pojedynczy element można podzielić według nazwy:
> foo["tac"] tac 22
Lub listę:
> foo[["tac"]] [1] 22
źródło
c(12,22,33)
tej struktury słownikowej R foo?unlist(lapply(FUN=function(a){foo[[a]]},X = 1:length(foo)))
jest bardzo niewygodne. Jakaś gotowa funkcja do tego? Przeniosłem pytanie tutajAby nieco rozszerzyć odpowiedź Calimo, przedstawiam jeszcze kilka rzeczy, które mogą się przydać podczas tworzenia tych quasi słowników w R:
a) jak zwrócić wszystkie WARTOŚCI słownika:
>as.numeric(foo) [1] 12 22 33
b) sprawdź, czy słownik ZAWIERA KLUCZ:
>'tic' %in% names(foo) [1] TRUE
c) jak DODAĆ NOWY klucz, parę wartości do słownika:
wyniki:
tic tac toe tic2 12 22 33 44
d) jak spełnić wymóg PRAWDZIWEGO SŁOWNIKA - aby klucze NIE MOGły się powtarzać (UNIKALNE KLUCZE)? Musisz połączyć b) ic) i zbudować funkcję, która sprawdza, czy istnieje taki klucz i robić co chcesz: np. Nie zezwalaj na wstawianie, aktualizuj wartość, jeśli nowy różni się od starego, lub przebudowuj jakoś klucz (np. dodaje do niego pewną liczbę, więc jest unikalna)
e) jak USUNĄĆ parę WEDŁUG KLUCZA ze słownika:
źródło
c(foo, tic2=NULL)
. Jakieś obejście?Powodem używania słowników w pierwszej kolejności jest wydajność. Chociaż prawdą jest, że możesz używać nazwanych wektorów i list do zadania, problem polega na tym, że stają się one dość powolne i wymagają większej ilości pamięci z większą ilością danych.
Jednak wielu ludzi nie wie, że R ma rzeczywiście wbudowaną strukturę danych słownikowych: środowiska z opcją
hash = TRUE
Zobacz poniższy przykład, jak to działa:
# 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
Edycja : Na podstawie tej odpowiedzi napisałem post na blogu z większym kontekstem: http://blog.ephorie.de/hash-me-if-you-can
źródło
Skrót pakietu jest już dostępny: https://cran.r-project.org/web/packages/hash/hash.pdf
Przykłady
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"
źródło
Krótsza odmiana odpowiedzi Dirka:
# 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"
źródło
Tylko skomentuję, że
table
próbując „sfałszować” słownik również można uzyskać dużo kilometrów , np> 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"
itp.
źródło
as.numeric()
jest to konieczne. Tabela jest już numeryczna. Możesz uzyskać ten sam wynik dziękinames(t[order(t)])