У меня тривиальный вопрос: мне не удалось найти структуру данных словаря в R, поэтому я использовал вместо этого список (например, «слово» -> число). Итак, прямо сейчас у меня проблема, как получить список ключей. Кто-нибудь знает?
93
environment
тип используется в R, но он менее распространен / менее известен.Вам даже не нужны списки, если все ваши «числовые» значения относятся к одному и тому же режиму. Если я возьму пример Дирка Эддельбюттеля:
> foo <- c(12, 22, 33) > names(foo) <- c("tic", "tac", "toe") > foo tic tac toe 12 22 33 > names(foo) [1] "tic" "tac" "toe"
Списки требуются только в том случае, если ваши значения являются либо смешанными (например, символы и числа), либо векторами.
И для списков, и для векторов отдельный элемент может быть разбит на подмножество по имени:
> foo["tac"] tac 22
Или для списка:
> foo[["tac"]] [1] 22
источник
c(12,22,33)
этой структуры R в стиле словаря foo?unlist(lapply(FUN=function(a){foo[[a]]},X = 1:length(foo)))
очень неудобно. Есть готовая функция для этого? Переехал вопрос здесьЧтобы немного расширить ответ Calimo, я представляю еще несколько вещей, которые могут оказаться полезными при создании этих квази-словарей в R:
а) как вернуть все ЗНАЧЕНИЯ словаря:
>as.numeric(foo) [1] 12 22 33
б) проверьте, СОДЕРЖИТ ли словарь КЛЮЧ:
>'tic' %in% names(foo) [1] TRUE
в) как ДОБАВИТЬ НОВЫЙ ключ, пару значений в словарь:
полученные результаты:
tic tac toe tic2 12 22 33 44
г) как выполнить требование НАСТОЯЩЕГО СЛОВАРА - что ключи НЕ МОГУТ повторяться (УНИКАЛЬНЫЕ КЛЮЧИ)? Вам нужно объединить b) и c) и функцию сборки, которая проверяет, существует ли такой ключ, и делать то, что вы хотите: например, не разрешать вставку, обновлять значение, если новое отличается от старого, или перестраивать каким-то образом ключ (например, добавляет к нему некоторое число, чтобы оно было уникальным)
д) как УДАЛИТЬ пару ПО КЛЮЧУ из словаря:
источник
c(foo, tic2=NULL)
. Любая работа?Причина использования словарей в первую очередь - это производительность. Хотя это правильно, что вы можете использовать именованные векторы и списки для задачи, проблема в том, что они становятся довольно медленными и требуют памяти с большим количеством данных.
Однако многие люди не знают, что R действительно имеет встроенную структуру данных словаря: среды с параметром
hash = TRUE
См. Следующий пример, как заставить его работать:
# 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
Изменить : на основе этого ответа я написал сообщение в блоге с дополнительным контекстом: http://blog.ephorie.de/hash-me-if-you-can
источник
Теперь доступен хэш пакета : https://cran.r-project.org/web/packages/hash/hash.pdf
Примеры
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"
источник
Более короткий вариант ответа Дирка:
# 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"
источник
Я просто прокомментирую, что вы можете сэкономить много времени,
table
пытаясь "подделать" словарь, например> 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"
и т.п.
источник
as.numeric()
это необходимо. Таблица уже числовая. Вы можете получить тот же результат сnames(t[order(t)])