অনেক ভাষাতেই অস্তিত্বহীন কোনো মান বোঝানোর জন্য null বা none-এর মতো একটি উপায় থাকে। যেহেতু R তৈরি হয়েছে বিপুল পরিমাণ (প্রায়ই অগোছালো) ডেটা সামলানোর জন্য, তাই এতে শূন্যতার একাধিক রূপ রয়েছে।
মূল লক্ষ্য হলো অনুপস্থিত বা সন্দেহজনক মান চোখে পড়া মাত্রই তা চিহ্নিত করা, তারপর কোনো এক্সেপশন রেইজ না করেই কাজ চালিয়ে যাওয়া।
কোনো মান সত্যিই না থাকলে তা NULL দিয়ে বোঝানো হয়। C বা Python-এ যা হয়, তার সঙ্গে সম্ভবত এটিই সবচেয়ে বেশি মেলে।
v <- c() # zero-length vector
v
#> NULL
is.null(v)
#> [1] TRUE
অনেক ক্ষেত্রেই NULL মান একেবারে উপেক্ষা করা হয়:
c(2, 3, NULL, 5)
#> [1] 2 3 5
কোনো মান আছে, কিন্তু সেটি কী তা আমরা জানি না, এমন পরিস্থিতিতে NA ব্যবহার করা হয়। যেমন রাস্তায় চলাচলকারী গাড়ি গোনার সময় যে মানুষটি গুনছেন তিনি অসুস্থ হয়ে পড়তে পারেন, আবার স্বয়ংক্রিয় সেন্সর নষ্ট হয়ে যেতে পারে, কিন্তু গাড়ির চলাচল তো থামে না।
v <- c(1, 2, NA, 4, 5)
v
#> [1] 1 2 NA 4 5
is.na(v) # test for data gaps
#> [1] FALSE FALSE TRUE FALSE FALSE
তাই NA হলো একটি প্লেসহোল্ডার, যা মানুষকে সতর্ক করে দেয় যে এটি কীভাবে সামলানো হবে, সে বিষয়ে তাদের সিদ্ধান্ত নিতে হবে।
পরিসংখ্যানভিত্তিক ফাংশন সাধারণত ডিফল্টভাবেই NA রিটার্ন করে, যদি ডেটায় NA মান উপস্থিত থাকে। আপনি যদি চান এই মানগুলো উপেক্ষা করা হোক, তাহলে na.rm (NA remove) প্যারামিটার দিয়ে সেটি স্পষ্টভাবে জানিয়ে দিন:
v <- c(1, 2, NA, 4, 5)
mean(v)
#> [1] NA
mean(v, na.rm = TRUE)
#> [1] 3
"Not a Number"-এর সংক্ষিপ্ত রূপ NaN এমন পরিস্থিতিতে গণনার সমস্যা চিহ্নিত করে, যেখানে একটি সংখ্যা প্রত্যাশিত ছিল।
n <- c(0, 2, 4)
d <- c(0, 1, 2)
n / d
#> [1] NaN 2 2 # 0/0 is mathematically undefined
is.nan(n / d)
#> [1] TRUE FALSE FALSE
"অবৈধ" গণনার একমাত্র সম্ভাবনা এটি নয়। শূন্য দিয়ে ভাগ করলে, লব অশূন্য হলে, কোনো এরর ছাড়াই Inf বা -Inf রিটার্ন হয়।
1 / 0
#> [1] Inf
আশ্চর্যের বিষয় হলো, কোনো কিছু খালি কি না তা যাচাই করার আদর্শ কোনো উপায় R-এ নেই, যদিও কিছু থার্ড-পার্টি প্যাকেজ নিজেদের ফাংশন তৈরি করেছে, যেমন is.empty().
এমনকি একটি খালি ভেক্টর তৈরি করাও খুব একটা স্পষ্ট নয়। আগের একটি অংশে আমরা দেখেছি, কোনো আর্গুমেন্ট ছাড়া c() একটি ভেক্টর নয়, বরং NULL রিটার্ন করে।
is.vector(c())
#> [1] FALSE
logical() বা integer()-এর মতো ফাংশন একটি আর্গুমেন্ট নেয়, যা দিয়ে কাঙ্ক্ষিত দৈর্ঘ্য ঠিক করা যায়, আর তা শূন্যও হতে পারে।
z <- logical(0)
is.vector(z)
#> [1] TRUE
length(z)
#> [1] 0
আমরা একটি ভেক্টর তৈরি করে তার সব এলিমেন্টও মুছে ফেলতে পারি, যেমনটি ভেক্টর ধারণা পাতায় বর্ণনা করা হয়েছে। এতে উপযুক্ত টাইপের শূন্য দৈর্ঘ্যের একটি ভেক্টর পাওয়া যায়।
v <- 5
v[-1] # delete the first element
#> numeric(0)