R में शब्दकोशों / सूचियों के साथ कार्य करना


93

मेरे पास तुच्छ प्रश्न है: मैं आर में एक शब्दकोश डेटा संरचना नहीं पा सका, इसलिए मैंने इसके बजाय सूची का उपयोग किया (जैसे "शब्द" -> संख्या) तो, अभी मुझे समस्या है कि चाबियों की सूची कैसे प्राप्त करें। किसी को पता है?

जवाबों:


120

हाँ, listप्रकार एक अच्छा सन्निकटन है। आप names()'कुंजियों' को सेट और पुनः प्राप्त करने के लिए अपनी सूची में उपयोग कर सकते हैं :

> 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"
> 

18
ओपी के अप्रभावी दृष्टिकोण के बारे में एक शब्द के बिना प्रश्न का उत्तर देने के लिए +1।
मारेक

3
किसी शब्दकोश के लिए प्रॉक्सी के रूप में किसी सूची के इच्छित उपयोग के आधार पर, यह ध्यान में रखना समझदारी हो सकती है कि सूचियों के लिए "कुंजी" लुक O (1) के बजाय O (n) है, जो आप के लिए उम्मीद करेंगे एक डिक्शनरी (जिसमें हैश कीज़)।
egnha

4
हां, environmentआर में उस प्रकार का उपयोग किया जाता है, लेकिन यह कम सामान्य / कम ज्ञात है।
डिर्क एडल्डबुलेटेल

58

यदि आपके "नंबर" मान सभी एक ही मोड के हैं, तो आपको सूचियों की भी आवश्यकता नहीं है। अगर मैं डिर्क एडल्डबुलेट का उदाहरण लेता हूं:

> 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

1
आप c(12,22,33)इस शब्दकोश-शैली आर संरचना फू की सूची कैसे प्राप्त कर सकते हैं ? unlist(lapply(FUN=function(a){foo[[a]]},X = 1:length(foo)))बहुत असुविधाजनक है। इसके लिए कोई तैयार कार्य? यहां
hhh

18

Calimo का थोड़ा सा उत्तर देने के लिए मैं कुछ और चीज़ें प्रस्तुत करता हूँ जो आपको R में इस अर्ध कोश को बनाते समय उपयोगी लग सकती हैं:

क) शब्दकोश के सभी मूल्यों को वापस कैसे करें:

>as.numeric(foo)
[1] 12 22 33

बी) जांचें कि क्या शब्दकोश कुंजी:

>'tic' %in% names(foo)
[1] TRUE

ग) कैसे जोड़ें नई कुंजी, मूल्य जोड़ी को शब्दकोश:

ग (foo, tic2 = 44)

परिणाम:

tic       tac       toe     tic2
12        22        33        44 

घ) REAL DICTIONARY की आवश्यकता को कैसे पूरा किया जाए - कि कुंजियाँ दोहराएं नहीं (UNIQUE KEYS)? आपको बी) और सी) को संयोजित करने और फ़ंक्शन का निर्माण करने की आवश्यकता है जो यह सत्यापित करता है कि क्या इस तरह की कुंजी है, और आप जो चाहते हैं वह करें: जैसे कि प्रविष्टि को अनुमति न दें, यदि नया पुराने से अलग है, या किसी तरह कुंजी को फिर से बनाएँ तो मान को अपडेट करें (जैसे इसमें कुछ नंबर जोड़ता है इसलिए यह अद्वितीय है)

ई) कैसे शब्दकोश से कुंजी जोड़ी द्वारा DELETE करने के लिए:

foo <-foo [जो (foo! = foo [[ "टैक"]])]


क्या मैं ऐसी कुंजी जोड़ सकता हूं जिसमें रिक्त स्थान हो, जैसे 'अजीब कुंजी'?
user1700890

साथ ही ऐसा कुछ काम नहीं करता है c(foo, tic2=NULL)। चारों ओर कोई काम?
user1700890

15

पहले स्थान पर शब्दकोशों का उपयोग करने का कारण प्रदर्शन है। यद्यपि यह सही है कि आप नामित वैक्टर और सूचियों का उपयोग कर सकते हैं कार्य के लिए समस्या यह है कि वे अधिक धीमी गति से और अधिक डेटा के साथ मेमोरी मेमोरी बन रहे हैं।

फिर भी बहुत से लोग यह नहीं जानते कि आर में वास्तव में एक इनबिल्ट डिक्शनरी डेटा संरचना है: विकल्प के साथ वातावरण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


क्या यह बहुस्तरीय संबंधों के लिए काम करता है? उदाहरण के लिए tic = 1 और tic = 17
skan

@skan: आप इसे क्यों नहीं आज़माते?
vonjd

नामों के साथ सूचियों का उपयोग करने के स्थान पर इस दृष्टिकोण का उपयोग करते हुए मेरे चलने का समय 6 मिनट से 1 सेकंड तक कम हो गया! मैं समझता हूं कि यह ठीक है, लेकिन क्या कोई इस बात की पुष्टि कर सकता है कि किसी सूची में नाम खोजते समय किस तरह का खोज प्रयोग किया जाता है? क्या यह केवल नाम मिलान के तहत सूची के माध्यम से पुनरावृत्ति है? मैं यह समझना चाहता हूं कि सूचियां इतनी धीमी क्यों हैं, साथ ही बड़ी संख्या में चाबियों के लिए इतनी तेजी क्यों है?
फिल

@vonjd मैं R में शब्दकोश का उपयोग करने की कोशिश कर रहा हूं और यह कार्यान्वयन पाया गया। हालांकि, क्या यह तब भी काम करता है जब प्रत्येक मूल्य कुंजियों की एक जोड़ी के साथ जुड़ा हो? पहले ही, आपका बहुत धन्यवाद।
Savi

@ शाना: क्या आप इसका एक उदाहरण दे सकते हैं जिसका आप बिल्कुल मतलब है?
vonjd

9

पैकेज हैश अब उपलब्ध है: 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"

आप कई मान कैसे जोड़ सकते हैं? मैंने कुंजी को दोहराने की कोशिश की है, लेकिन यह केवल अंतिम मूल्य संग्रहीत करता है। मैंने सूचियों को असाइन करने की भी कोशिश की है, लेकिन यह काम नहीं करता
skan

शब्दकोश कुंजी प्रति कुंजी कई मूल्यों को संग्रहीत नहीं करती है। आप एक कुंजी को एक सूची असाइन कर सकते हैं यदि आप चाहते हैं।
BallpointBen

7

डिर्क के उत्तर का छोटा रूपांतर:

# 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"

4

मैं सिर्फ टिप्पणी करूँगा कि 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)])
रिच स्क्रीवेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.