वे

वेक्टर में R

1 अभ्यास

वेक्टर के बारे में

R में एक vector (तकनीकी रूप से atomic vector) एक ही type की वैल्यू का संग्रह होता है: आम तौर पर integer, numeric, character, logical; और कभी-कभार complex या raw। ये मेमोरी में लगातार संग्रहीत रहते हैं, किसी C ऐरे की तरह।

अगर इनपुट मिले-जुले हों, तो R चुपचाप उन सबको एक ही आम टाइप में ढाल देता है, आम तौर पर character में, जिससे अनपेक्षित परिणाम मिल सकते हैं।

v <- c(2, 5.4, "txt")
v
#> [1] "2"   "5.4" "txt"
typeof(v)
#> [1] "character"

वेक्टर बनाना

अगर आपके पास सारी वैल्यू पहले से हैं, तो c() इस्तेमाल कीजिए (यह "concatenate" का छोटा रूप है):

x <- 10
v <- c(4, 7, x)

c() फंक्शन बहुत लचीला है, और इसके इनपुट में दूसरे वेक्टर और रेंज भी शामिल हो सकते हैं। c() किसी भी संख्या और किस्म के इनपुट ले सकता है, और उन्हें मिलाकर एक ही वेक्टर बना देता है।

अगर वेक्टर शुरू में छोटा हो और प्रोग्राम चलने के दौरान बहुत बढ़ जाए (जैसे किसी लूप में वैल्यू जोड़ते जाना), तो पहले से एक लंबा वेक्टर बना लेना काफी तेज़ हो सकता है, जिसे बाद में असली डेटा से भरा जा सकता है:

v <- vector(length = 100) 

इससे ऑब्जेक्ट की कॉपी बनाने की ज़रूरत कम हो जाती है, जो लंबे वेक्टर के लिए धीमा और बहुत मेमोरी लेने वाला काम है।

रेंज, सीक्वेंस और दोहराव

लगातार वैल्यू की एक रेंज के लिए (बढ़ती या घटती हुई) आप : संकेतन इस्तेमाल कर सकते हैं

v <- 1:5 # equivalent to c(1, 2, 3, 4, 5)
w <- 10:7 # c(10, 9, 8, 7)

R में रेंज कोई अलग डेटा टाइप नहीं हैं, बल्कि वेक्टर बनाने का एक छोटा तरीका भर हैं।

seq() फंक्शन इस पर ज़्यादा बारीक नियंत्रण देता है:

# specify step size
seq(2, 11, by = 3) # c(2, 5, 8, 11)

# specify number of values, evenly-spaced
seq(2.5, 4, length.out = 5) # c(2.500, 2.875, 3.250, 3.625, 4.000) 

rep() फंक्शन से दोहराए जाने वाले पैटर्न बनाना आसान हो जाता है:

count <- 3
rep(7, count)
#> [1] 7 7 7

rep(1:3, count)
#> [1] 1 2 3 1 2 3 1 2 3

rep(1:3, each = 2) # the "each" keyword is required in this case
#> [1] 1 1 2 2 3 3

कुछ रेंज पहले से स्थिरांक के रूप में मौजूद हैं:

letters  # LETTERS is the UPPERCASE equivalent
#> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"

month.name
#> [1] "January"   "February"  "March"     "April"     "May"       "June"      "July"      "August"   
#> [9] "September" "October"   "November"  "December" 

month.abb
#> [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"

अंकगणित

ऑपरेशन अपने आप वेक्टर के हर एलिमेंट पर एक-एक करके लागू होते हैं। दूसरी भाषाओं में आम लूप, लिस्ट कॉम्प्रिहेंशन और रिकर्शन की यहाँ ज़रूरत नहीं पड़ती, और (परफॉर्मेंस की वजह से) जहाँ तक हो सके इनसे बचना चाहिए।

2 + 1:3     # c(3, 4, 5)
2 * 1:3     # c(2, 4, 6)
12 / 1:3    # c(12  6  4)
2 ^ (1:3)   # c(2, 4, 8) : exponentiation, operator precedence order here needs ()

वेक्टर के जोड़े भी काम करते हैं, जिनके एलिमेंट जोड़ी-जोड़ी में लिए जाते हैं:

v <- 1:3
w <- 5:7

v + w
#> [1]  6  8 10

v * w
#> [1]  5 12 21

v ^ w
#> [1]    1   64 2187

यह पहली नज़र में लगता है उससे कहीं ज़्यादा शक्तिशाली है, और आगे के कॉन्सेप्ट में इस पर और चर्चा होगी।

वेक्टर के एलिमेंट तक पहुँचना

कई भाषाओं की तरह, हम ब्रैकेट में इंडेक्स इस्तेमाल कर सकते हैं:

v <- 4:7
v[2]
#> [1] 5
v[2:4]
#> [1] 5 6 7

लेकिन ध्यान रखिए: R डिफाल्ट रूप से 1 से शुरू होने वाली इंडेक्सिंग इस्तेमाल करता है। यह वैज्ञानिक भाषाओं (Fortran, Matlab, Julia) में आम है, लेकिन C और उसके बाद आने वाली कई भाषाओं की 0 से शुरू होने वाली इंडेक्सिंग से अलग है।

रेंज का इस्तेमाल ऊपर के उदाहरण की तरह किया जा सकता है, और बहुत लचीले c() फंक्शन में भी:

v <- c(4, 7, 10)
w <- c(2, v[2:3], 11) # c(2, 7, 10, 11)

vectors (R की ज़्यादातर चीज़ों की तरह) बदले जा सकने वाले होते हैं, और उसी लचीले सिंटैक्स से एक या कई एलिमेंट में वैल्यू लिखी जा सकती है:

v <- 1:10
v[2] <- 42
v[4:6] <- c(11, 12, 13)
v
#> [1]  1 42  3 11 12 13  7  8  9 10

ऋणात्मक इंडेक्स

दूसरी भाषाओं से परिचित प्रोग्रामर शायद सोचें कि v[-1] वेक्टर के अंतिम एलिमेंट तक पहुँचने का तरीका है। गलत! इसके लिए tail() इस्तेमाल कीजिए।

v <- c(2, 4, 6) # defaults to last 6 entries
tail(v)
#> [1] 2 4 6
tail(v, n=1) # just the last entry
#> [1] 6

ऋणात्मक इंडेक्स वास्तव में किसी एलिमेंट को हटाने का तरीका हैं:

v <- c(2, 4, 6)
v[-2]
#> [1] 2 6  # second element gone

यह वेक्टर की एक छोटी कॉपी लौटाता है। v खुद नहीं बदलता।

वेक्टर पर शर्तें

वेक्टर पर तुलना लागू करने से उतनी ही लंबाई का बूलियन वेक्टर लौटता है। यह all() और any() जैसे फंक्शन में बहुत काम आ सकता है:

v <- c(4, 7, 10)
v >= 6
#> [1] FALSE  TRUE  TRUE
all(v > 6)
#> [1] FALSE    # not all elements match this condition
any(v > 6)
#> [1] TRUE     # at least one element matches

ज़्यादा जटिल लॉजिकल एक्सप्रेशन के लिए & और | ऑपरेटर इस्तेमाल करना ज़रूरी है, जो वेक्टर पर काम करते हैं। दोहरे अक्षर वाले && और || सिर्फ अकेली वैल्यू की तुलना के लिए हैं, जैसा कि [बूलियन कॉन्सेप्ट][concept-boolean] में बताया गया है।

v <- c(4, 7, 10)
v %% 2 == 0 & v > 5
#> [1] FALSE FALSE  TRUE

R में वेक्टर हर जगह हैं

आगे के विषयों में हम इस पर फिर लौटेंगे। फिलहाल, कंसोल में आउटपुट का फॉर्मैट ध्यान से देखिए:

1:20
#> [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17
#> [18] 18 19 20

लाइनें [ ] में संख्याओं से शुरू होती हैं, जो पहले एलिमेंट का इंडेक्स बताती हैं (लंबे वेक्टर कई लाइनों में लिपटने पर यह काम आता है)। लेकिन अकेली वैल्यू के आगे [1] क्यों लगता है?

Note

R में सचमुच कोई स्केलर वैल्यू नहीं होती!

जो एक अकेली संख्या या अक्षर दिखता है, वह वास्तव में लंबाई 1 का एक वेक्टर होता है।

हमने इसका संकेत बेसिक्स और बूलियन कॉन्सेप्ट में न्यूमेरिक और लॉजिकल टाइप के साथ पहले ही देख लिया है।

संकेतन पर एक बात

ऊपर बताए गए वेक्टर को अधिक औपचारिक रूप से atomic vectors कहा जाता है। ऐसा इसलिए है क्योंकि इनमें सिर्फ सरल, अविभाज्य (इसीलिए "atomic") वैल्यू ही रखी जा सकती हैं, जैसे numeric, character, boolean। ज़्यादा जटिल ढाँचे मिलकर recursive vectors बना सकते हैं, जिनके बारे में lists पर चर्चा करते समय बताया जाएगा।

GitHub के ज़रिए संपादित करें यह लिंक नई विंडो या टैब में खुलता है।

वेक्टर सीखिए