खोज…


हैश नक्शे के रूप में वातावरण

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

परिचय

यद्यपि R एक देशी हैश टेबल संरचना प्रदान नहीं करता है, इसी तरह की कार्यक्षमता इस तथ्य का लाभ उठाकर प्राप्त की जा सकती है कि environment ऑब्जेक्ट new.env (डिफ़ॉल्ट रूप से) से लौटा new.env कुंजी लुकअप प्रदान करता है। निम्नलिखित दो कथन समतुल्य हैं, क्योंकि hash पैरामीटर TRUE चूक करता है:

H <- new.env(hash = TRUE)
H <- new.env() 

इसके अतिरिक्त, कोई निर्दिष्ट कर सकता है कि आंतरिक हैश तालिका size पैरामीटर के माध्यम से एक विशेष आकार के साथ पूर्व-आबंटित है, जिसका डिफ़ॉल्ट मान 29 है। अन्य सभी R वस्तुओं की तरह, environment अपनी स्मृति का प्रबंधन करता है और आवश्यकतानुसार क्षमता में वृद्धि करेगा। , इसलिए जब size लिए एक गैर-डिफ़ॉल्ट मूल्य का अनुरोध करना आवश्यक नहीं है, तो ऐसा करने में थोड़ा सा प्रदर्शन लाभ हो सकता है यदि ऑब्जेक्ट (अंततः) में बहुत बड़ी संख्या में तत्व होंगे। यह ध्यान देने योग्य है कि size माध्यम से अतिरिक्त स्थान आवंटित करना, अपने आप में, बड़े स्मृति पदचिह्न के साथ किसी वस्तु में परिणाम नहीं करता है:

object.size(new.env())
# 56 bytes

object.size(new.env(size = 10e4))
# 56 bytes 

निवेशन

तत्वों की प्रविष्टि [[<- या $<- environment वर्ग के लिए प्रदान की गई विधियों का उपयोग करके की जा सकती है, लेकिन "एकल ब्रैकेट" असाइनमेंट ( [<- ) का उपयोग करके नहीं :

H <- new.env()

H[["key"]] <- rnorm(1)

key2 <- "xyz"
H[[key2]] <- data.frame(x = 1:3, y = letters[1:3])

H$another_key <- matrix(rbinom(9, 1, 0.5) > 0, nrow = 3)

H["error"] <- 42
#Error in H["error"] <- 42 : 
#  object of type 'environment' is not subsettable 

R के अन्य पहलुओं की तरह, पहला तरीका ( object[[key]] <- value ) आम तौर पर दूसरे के लिए पसंद किया जाता है ( object$key <- value ) क्योंकि पूर्व मामले में, एक वैरिएबल का उपयोग शाब्दिक मान के बजाय शायद किया जा सकता है। (उदाहरण के लिए key2 ऊपर के उदाहरण में)।

जैसा कि आम तौर पर हैश मैप कार्यान्वयन के साथ होता है, environment ऑब्जेक्ट डुप्लिकेट कुंजियों को संग्रहीत नहीं करेगा। मौजूदा कुंजी के लिए की-वैल्यू पेयर सम्मिलित करने का प्रयास पहले संग्रहीत मान को बदल देगा:

H[["key3"]] <- "original value"

H[["key3"]] <- "new value"

H[["key3"]]
#[1] "new value"

मुख्य लुकअप

इसी तरह, तत्वों को [[ या $ साथ एक्सेस किया जा सकता है, लेकिन [ :]

H[["key"]]
#[1] 1.630631
 
H[[key2]]   ## assuming key2 <- "xyz"
#   x y
# 1 1 a
# 2 2 b
# 3 3 c

H$another_key
#       [,1]  [,2]  [,3]
# [1,]  TRUE  TRUE  TRUE
# [2,] FALSE FALSE FALSE
# [3,]  TRUE  TRUE  TRUE

H[1]
#Error in H[1] : object of type 'environment' is not subsettable

हैश मैप का निरीक्षण

साधारण environment होने के नाते, हैश मैप का निरीक्षण विशिष्ट तरीकों से किया जा सकता है:

names(H)
#[1] "another_key" "xyz"         "key"         "key3"       

ls(H)
#[1] "another_key" "key"         "key3"        "xyz"        
 
str(H)
#<environment: 0x7828228> 
 
ls.str(H)
# another_key :  logi [1:3, 1:3] TRUE FALSE TRUE TRUE FALSE TRUE ...
# key :  num 1.63
# key3 :  chr "new value"
# xyz : 'data.frame':    3 obs. of  2 variables:
#  $ x: int  1 2 3
#  $ y: chr  "a" "b" "c"

rm का उपयोग करके तत्वों को हटाया जा सकता है:

rm(list = c("key", "key3"), envir = H)

ls.str(H)
# another_key :  logi [1:3, 1:3] TRUE FALSE TRUE TRUE FALSE TRUE ...
# xyz : 'data.frame':    3 obs. of  2 variables:
#  $ x: int  1 2 3
#  $ y: chr  "a" "b" "c"

लचीलापन

हैश टेबल के रूप में environment वस्तुओं का उपयोग करने के प्रमुख लाभों में से एक उनके मूल्य को किसी भी प्रकार की वस्तु के रूप में संग्रहीत करने की उनकी क्षमता है, यहां तक कि अन्य environment भी हैं :

H2 <- new.env()

H2[["a"]] <- LETTERS
H2[["b"]] <- as.list(x = 1:5, y = matrix(rnorm(10), 2))
H2[["c"]] <- head(mtcars, 3)
H2[["d"]] <- Sys.Date()
H2[["e"]] <- Sys.time()
H2[["f"]] <- (function() {
    H3 <- new.env()
    for (i in seq_along(names(H2))) {
        H3[[names(H2)[i]]] <- H2[[names(H2)[i]]]
    }
    H3
})()

ls.str(H2)
# a :  chr [1:26] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" ...
# b : List of 5
#  $ : int 1
#  $ : int 2
#  $ : int 3
#  $ : int 4
#  $ : int 5
# c : 'data.frame':    3 obs. of  11 variables:
#  $ mpg : num  21 21 22.8
#  $ cyl : num  6 6 4
#  $ disp: num  160 160 108
#  $ hp  : num  110 110 93
#  $ drat: num  3.9 3.9 3.85
#  $ wt  : num  2.62 2.88 2.32
#  $ qsec: num  16.5 17 18.6
#  $ vs  : num  0 0 1
#  $ am  : num  1 1 1
#  $ gear: num  4 4 4
#  $ carb: num  4 4 1
# d :  Date[1:1], format: "2016-08-03"
# e :  POSIXct[1:1], format: "2016-08-03 19:25:14"
# f : <environment: 0x91a7cb8> 

ls.str(H2$f)
# a :  chr [1:26] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" ...
# b : List of 5
#  $ : int 1
#  $ : int 2
#  $ : int 3
#  $ : int 4
#  $ : int 5
# c : 'data.frame':    3 obs. of  11 variables:
#  $ mpg : num  21 21 22.8
#  $ cyl : num  6 6 4
#  $ disp: num  160 160 108
#  $ hp  : num  110 110 93
#  $ drat: num  3.9 3.9 3.85
#  $ wt  : num  2.62 2.88 2.32
#  $ qsec: num  16.5 17 18.6
#  $ vs  : num  0 0 1
#  $ am  : num  1 1 1
#  $ gear: num  4 4 4
#  $ carb: num  4 4 1
# d :  Date[1:1], format: "2016-08-03"
# e :  POSIXct[1:1], format: "2016-08-03 19:25:14"

सीमाएं

हैश मैप के रूप में environment वस्तुओं का उपयोग करने की एक प्रमुख सीमा यह है कि आर के कई पहलुओं के विपरीत, तत्व की तलाश / सम्मिलन के लिए वैश्वीकरण का समर्थन नहीं किया जाता है:

names(H2)
#[1] "a" "b" "c" "d" "e" "f"

H2[[c("a", "b")]]
#Error in H2[[c("a", "b")]] : 
#  wrong arguments for subsetting an environment
 
Keys <- c("a", "b")
H2[[Keys]]
#Error in H2[[Keys]] : wrong arguments for subsetting an environment

ऑब्जेक्ट में संग्रहीत डेटा की प्रकृति के आधार पर, एक ही बार में कई तत्वों को असाइन करने के लिए vapply या list2env का उपयोग करना संभव हो सकता है:

E1 <- new.env()
invisible({
    vapply(letters, function(x) {
        E1[[x]] <- rnorm(1)
        logical(0)
    }, FUN.VALUE = logical(0))
})

all.equal(sort(names(E1)), letters)
#[1] TRUE

Keys <- letters
E2 <- list2env(
    setNames(
        as.list(rnorm(26)),
        nm = Keys), 
    envir = NULL,
    hash = TRUE
)

all.equal(sort(names(E2)), letters)
#[1] TRUE

उपरोक्त में से कोई भी विशेष रूप से संक्षिप्त नहीं है, लेकिन लूप आदि के for उपयोग करना बेहतर हो सकता है, जब की-वैल्यू जोड़े की संख्या बड़ी हो।

पैकेज: हैश

हैश पैकेज आर। में एक हैश संरचना प्रदान करता है। हालांकि, यह आवेषण के लिए समय की शर्तों और इसे एक हैश के रूप में पर्यावरण का उपयोग करने के लिए प्रतिकूल तुलना करता है। यह प्रलेखन बस अपने अस्तित्व को स्वीकार करता है और उपर्युक्त कारणों के लिए नीचे नमूना समय कोड प्रदान करता है। कोई पहचाना हुआ मामला नहीं है जहाँ आज आर कोड में हैश एक उपयुक्त समाधान है।

विचार करें:

# Generic unique string generator
unique_strings <- function(n){
    string_i <- 1
    string_len <- 1
    ans <- character(n)
    chars <- c(letters,LETTERS)
    new_strings <- function(len,pfx){
    for(i in 1:length(chars)){
        if (len == 1){
        ans[string_i] <<- paste(pfx,chars[i],sep='')
        string_i <<- string_i + 1
        } else {
        new_strings(len-1,pfx=paste(pfx,chars[i],sep=''))
        }
        if (string_i > n) return ()
    }
    }
    while(string_i <= n){
    new_strings(string_len,'')
    string_len <- string_len + 1
    }
    sample(ans)
}

# Generate timings using an enviornment
timingsEnv <- plyr::adply(2^(10:15),.mar=1,.fun=function(i){
    strings <- unique_strings(i)
    ht1 <- new.env(hash=TRUE)
    lapply(strings, function(s){ ht1[[s]] <<- 0L})
    data.frame(
    size=c(i,i),
    seconds=c(
        system.time(for (j in 1:i) ht1[[strings[j]]]==0L)[3]),
    type = c('1_hashedEnv')
    )
})

timingsHash <- plyr::adply(2^(10:15),.mar=1,.fun=function(i){
    strings <- unique_strings(i)
    ht <- hash::hash()
    lapply(strings, function(s) ht[[s]] <<- 0L)
    data.frame(
    size=c(i,i),
    seconds=c(
        system.time(for (j in 1:i) ht[[strings[j]]]==0L)[3]),
    type = c('3_stringHash')
    )
})

पैकेज: listenv

हालांकि package:listenv पर्यावरण के लिए सूची-जैसा इंटरफ़ेस लागू करता है, हैश जैसे उद्देश्यों के लिए वातावरण के सापेक्ष इसका प्रदर्शन हैश पुनर्प्राप्ति पर खराब है । हालाँकि, यदि इंडेक्स संख्यात्मक हैं, तो यह रिट्रीवल पर काफी तेज़ हो सकता है। हालांकि, उनके पास अन्य फायदे हैं, उदाहरण के लिए package:future के साथ संगतता package:future । उस उद्देश्य के लिए इस पैकेज को कवर करना वर्तमान विषय के दायरे से परे है। हालांकि, यहां दिए गए समय कोड का उपयोग पैकेज के लिए उदाहरण के साथ संयोजन में किया जा सकता है: लेखन समय के लिए हैश।

timingsListEnv <- plyr::adply(2^(10:15),.mar=1,.fun=function(i){
    strings <- unique_strings(i)
    le <- listenv::listenv()
    lapply(strings, function(s) le[[s]] <<- 0L)
    data.frame(
    size=c(i,i),
    seconds=c(
        system.time(for (k in 1:i) le[[k]]==0L)[3]),
    type = c('2_numericListEnv')
    )
})


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow