मैं आर में एक सूची में फाइलों के अनुक्रम को लोड करने की कोशिश कर रहा हूं। यहां नीचे उदाहरण और कोड का उपयोग किया गया है।

## data
val <- c(1:5)
save(val, file='test1.rda')
val <- c(6:10)
save(val, file='test2.rda')

## file names
files = paste0('test',c(1:2), '.rda')
# "test1.rda" "test2.rda"

## use apply to load data into a list 
res <- lapply(files, function(x) load(x))
res
# [[1]]
# [1] "val" # ??? supposed to be 1,2,3,4,5
# 
# [[2]]
# [1] "val" # ??? supposed to be 6,7,8,9,10


## use for loops to load data
for (i in c(1:2)){
  load(files[i])
}
# data sets are loaded as expected

मैं नहीं देख सकता कि apply + load फ़ंक्शन सही सूची क्यों नहीं लौटा रहा है। मैं इसकी सराहना करता हूं अगर कोई मुझे सही दिशा में इंगित कर सकता है।

0
Xiang 5 सितंबर 2021, 02:50

2 जवाब

सबसे बढ़िया उत्तर

load फ़ंक्शन सहेजे गए R ऑब्जेक्ट्स को असाइन करने का एक अच्छा तरीका नहीं है क्योंकि यह ऑब्जेक्ट को सीधे आपके वातावरण में लोड करता है (जैसा कि आपने अपने लूप में किया था, एक नया नामित ऑब्जेक्ट निर्दिष्ट किए बिना)

saveRDS और readRDS आपके परिवेश में एक सहेजी गई फ़ाइल को किसी नए ऑब्जेक्ट को असाइन करने में आपकी सेवा करेंगे;

val <- c(1:5)
saveRDS(val, file='test1.rds')
val <- c(6:10)
saveRDS(val, file='test2.rds')

files = paste0('test',c(1:2), '.rds')

res <- lapply(files, function(x) readRDS(x))
res

आउटपुट;

1. 1 2 3 4 5
2. 6 7 8 9 10
3
Samet Sökel 5 सितंबर 2021, 00:09

बॉटम लाइन अप फ्रंट: load कॉलिंग परिवेश में डेटा लोड करता है, और यह for लूप और lapply से चलाने पर बहुत अलग होता है। डेटा लोड होने के किस परिवेश में बाध्य करने के लिए आप इसे ओवरराइड कर सकते हैं।

यदि आप ?load पढ़ते हैं, तो आपको envir= तर्क दिखाई देगा:

Usage:

     load(file, envir = parent.frame(), verbose = FALSE)
     
Arguments:

    file: a (readable binary-mode) connection or a character string
          giving the name of the file to load (when tilde expansion is
          done).

   envir: the environment where the data should be loaded.

 verbose: should item names be printed during loading?

चूंकि डिफ़ॉल्ट parent.frame() है, इसका मतलब है कि इसे lapply के भीतर परिभाषित परिवेश में लोड किया जा रहा है, वैश्विक परिवेश में नहीं।

प्रदर्शन:

for (i in 1:2) { print(environment()); }
# <environment: R_GlobalEnv>
# <environment: R_GlobalEnv>
ign <- lapply(1:2, function(ign) print(environment()))
# [[1]]
# <environment: 0x000000006f54b838>                # not R_GlobalEnv, aka .GlobalEnv
# [[2]]
# <environment: 0x000000006f54de58>

इसके अलावा, चूंकि

Value:

     A character vector of the names of objects created, invisibly.

इसका अर्थ यह है कि res <- lapply(files, load) हमेशा केवल एक character वेक्टर लौटाएगा, न कि स्वयं मान।

जबकि मैं समेट सोकेल के इस सिद्धांत से सहमत हूं कि readRDS एक अधिक कार्यात्मक इंटरफ़ेस प्रदान करता है (अर्थात्: यह कुछ देता है, यह केवल साइड-इफ़ेक्ट पर काम नहीं करता है), समाधान बहुत मुश्किल नहीं है :

  1. वैश्विक वातावरण में लोड करें:

    res <- lapply(files, load, envir = .GlobalEnv)
    

    यह res में लोड किए गए सभी चरों का नाम और वैश्विक परिवेश में प्रदर्शित होने वाला सभी डेटा लौटाएगा।

  2. उपयोगकर्ता द्वारा परिभाषित वातावरण में लोड करें:

    e <- new.env(parent = emptyenv())
    res <- lapply(files, load, envir = e)
    # all data is now in 'e'
    

    res में केवल नाम होंगे, लेकिन यह कार्यात्मक इंटरफ़ेस के थोड़ा करीब है जिसमें डेटा आपके द्वारा परिभाषित एक बहुत ही विशिष्ट स्थान पर जा रहा है।

    इसे जल्दी से खारिज न करें: यदि आप कभी भी अपने कोड को "उत्पादन" करना चुनते हैं जो सभी .rda फाइलों को लोड करता है, तो उसके लिए .GlobalEnv के अलावा किसी अन्य वातावरण में डेटा लोड करना अच्छा हो सकता है। एक के लिए, किसी फ़ंक्शन के अंदर लोड करना और डेटा को ग्लोबल में डालना वास्तव में खराब अभ्यास है, और यह आपके फ़ंक्शन के लिए हमेशा सुचारू रूप से काम नहीं कर सकता है। ठीक है, यह सिर्फ "एक" है, उत्पादन-प्रकार के फ़ंक्शन/पैकेज में साइड-इफेक्ट एक बुरी चीज है (आईएमओ): यह अक्सर पुनरुत्पादन को तोड़ देता है, यह वास्तव में उन उपयोगकर्ताओं के साथ गड़बड़ कर सकता है जिनके पास समान-नाम वाले चर होते हैं उनका पर्यावरण ... और उन्हें ओवरराइट करना एक अपरिवर्तनीय ऑपरेशन है जो जल्दी से क्रोध और खोई हुई उत्पादकता का कारण बन सकता है। कुछ गलत होने पर साइड-इफ़ेक्ट का निवारण करना भी बहुत मुश्किल होता है।

4
r2evans 5 सितंबर 2021, 00:56