این مفهوم گستردهای در R است. برای درک بهتر این امکانات، توجه به تعداد ابعاد ورودی و خروجی توابع مختلف میتواند مفید باشد.
پیشتر توابعی را دیدیم که یک بردار میگیرند و یک مقدار واحد و اسکالرمانند برمیگردانند:
v <- 1:5
length(v)
#> [1] 5
sum(v)
#> [1] 15
بسیاری از توابع آماری هم در این دسته قرار میگیرند، مانند mean().
برای بردارهای منطقی، all() و any() وجود دارند که یک TRUE یا FALSE واحد برمیگردانند.
بسیاری از توابع در R روی کل بردار عمل میکنند و اغلب خروجی برداری میدهند. این شامل بیشتر توابع ریاضی میشود:
sq <- c(4, 9, 16, 25)
sqrt(sq) # square root
#> [1] 2 3 4 5
این فقط مختصر و راحت نیست؛ نیاز به حلقهها، درک فهرست یا بازگشتی را هم که در زبانهای دیگر رایجاند از میان برمیدارد. در R، توابع برداری اغلب بسیار سریعتر از این تکنیکها اجرا میشوند.
شما احتمالاً بیش از آنچه فکر میکنید از توابع برداریشده استفاده کردهاید. اینها را مقایسه کنید:
v <- c(2, 7, 9)
w <- c(3, 1, 5)
v + w
#> [1] 5 8 14
"+"(v, w)
#> [1] 5 8 14
عملگرهای میانوندی که میشناسید فقط یک میانبر نگارشی برای تابع برداریشدهی زیرین هستند! در این مورد، "+"().
برای مرتبسازی یک بردار، sort() برای بازگرداندن مقادیر و order() برای بازگرداندن اندیسها وجود دارد:
v <- c("I", "am", "not", "in", "order")
sort(v)
#> [1] "am" "I" "in" "not" "order"
order(v)
#> [1] 2 1 4 3 5
حالت پیشفرض مرتبسازی بهصورت صعودی است.
در صورت نیاز decreasing = TRUE را مشخص کنید، یا از rev() برای معکوس کردن یک بردار موجود استفاده کنید.
v <- c("I", "am", "not", "in", "order")
sort(v, decreasing = TRUE)
#> [1] "order" "not" "in" "I" "am"
rev(1:4)
#> [1] 4 3 2 1
توابعی هم مانند cumsum() و cumprod() وجود دارند که خروجیهای برداری تجمعی تولید میکنند و بردار ورودی را از چپ به راست پردازش میکنند:
cumsum(1:5)
#> [1] 1 3 6 10 15 # sums
cumprod(1:5)
#> [1] 1 2 6 24 120 # equivalent to factorials
مثالهای بالا شبیه عملیات foldl در بسیاری از زبانهای تابعی هستند، با این تفاوت که خروجی یک بردار شامل همهی مقادیر میانی است.
میتوان از بسط این مفهوم برای مقایسهی بردارها هم استفاده کرد.
برای نمونه، تابع بیشینهی دوبهدو pmax() را در نظر بگیرید:
v
#> [1] 2 7 9
w
#> [1] 3 1 5
pmax(v, w)
#> [1] 3 7 9 # max of each pairwise comparison
این تابع و توابع مشابه آن، تعداد دلخواهی از بردارهای ورودی را هم میپذیرند، نه فقط دو تا.
مثال بالا از بردارهایی با طول برابر استفاده میکند. همانطور که در مفهوم پالایش بردار بحث شد، R برای گسترش بردارهایی که به نوعی «بیش از حد کوتاه» هستند از بازیافت استفاده میکند. تکرار میکنیم: از این کار با احتیاط استفاده کنید و ترجیحاً فقط با برداری با طول ۱.
pmax(v, 5)
#> [1] 5 7 9
این حالت کمتر رایج است، اما نوشتن توابعی که ظاهراً ورودی اسکالر و خروجی بردار دارند نسبتاً آسان است.
وقتی روی ورودی برداری اعمال شوند، خروجی یک matrix دوبعدی است (که در مفهومی بعدی پوشش داده شده است).