R یک زبان با نوعدهی پویا است، بنابراین بهطور کلی نیازی به مشخص کردن نوع یک متغیر نیست. نوع پیشفرض numeric است که معمولاً بهصورت یک عدد اعشاری با دقت دوگانه پیادهسازی میشود. برای اجبار به استفاده از اعداد صحیح ۳۲بیتی، از پسوند L استفاده کنید (مخفف Long).
به دست آوردن «نوع» یک شیء (به دلایل تاریخی) میتواند گیجکننده باشد.
توابع typeof() و class() شبیه هم هستند، اما ممکن است نتایج کمی متفاوتی برگردانند:
typeof(50)
#> [1] "double" # more specific: an implementation detail
typeof(50L)
##> [1] "integer"
class(50)
#> [1] "numeric" # less specific: ignores implementation details
class(50L)
#> [1] "integer"
ممکن است ارجاعهایی به mode() هم ببینید که شبیه typeof() است.
لطفاً mode() و storage.mode() را نادیده بگیرید.
اینها فقط برای سازگاری با نسخههای قبلی ارائه شدهاند.
عملگر انتساب ترجیحی <- است.
اگر در RStudio کار میکنید، میتوان آن را با میانبر صفحهکلید Alt-minus وارد کرد.
x <- 42
avogadro <- 6.02e23
mystr <- "Hello, World!"
استفاده از = بهجای <- اغلب اما نه همیشه کار میکند و چون سبک بدی است توصیه نمیشود.
عملگرها تقریباً مانند بسیاری از زبانهای دیگر هستند، هرچند %% و %/% غیرمعمولترند.
این نحوهی نگارش % راهی برای فراخوانی عملگرهای میانوندی است که بهصورت ماکرو پیادهسازی شدهاند.
2 + 3 # 5
2 - 3 # -1
2 * 3 # 6
2 / 3 # 0.6666667
8 %/% 3 # 2 (integer division)
8 %% 3 # 2 (remainder)
2 ^ 3 # 8 (exponential)
در R، علامت # یک کامنت یکخطی را شروع میکند.
برای کامنتهای چندخطی نحوهی نگارش جداگانهای وجود ندارد.
برای تعریف یک تابع:
squareit <- function(x) {
x * x
}
توابع میتوانند صفر یا چند آرگومان داشته باشند که با ویرگول از هم جدا میشوند.
پرانتزهای () برای function() لازماند، حتی اگر هیچ پارامتری وجود نداشته باشد.
میتوان برای آرگومانهای تابع مقادیر پیشفرض مشخص کرد، اما این مقادیر باید بعد از هر آرگومانی بیایند که پیشفرض ندارد و برای انتساب مقدار پیشفرض از = استفاده شود، نه <-.
بهعنوان یک مثال نسبتاً بیفایده:
squareit <- function(x = 42) {
x * x
}
squareit()
#> [1] 1764
آکولادهای { } برای بدنهی یکخطی تابع اکیداً لازم نیستند، اما آوردنشان سبک خوبی شمرده میشود.
R بهصورت خودکار مقدار نهایی یک تابع را برمیگرداند، همانطور که در مثالهای بالا دیدید.
میتوان از return() در هر جایی از بدنهی تابع استفاده کرد تا مقدار بازگشتی را صریح کنید.
این تابع مقدار مشخصشده را بلافاصله برمیگرداند و بدون اجرای باقی عبارتهای بدنه، تابع را خاتمه میدهد.
فراخوانی صریح return() معمولاً تنها زمانی لازم است که بخواهید به دلیلی زودتر از تابع خارج شوید و مقدار مشخصی برگردانید.
یک نمونه میتواند درون یک بند if-else باشد.
البته برخی توسعهدهندگان بهعنوان یک انتخاب سبک کدنویسی، بازگشت صریح را ترجیح میدهند.
فراخوانی یک تابع هم مانند بسیاری از زبانهای دیگر است:
squareit(3)
#> [1] 9
در مفاهیم بعدی خواهیم دید که نتیجهی 9 در واقع یک بردار با طول ۱ است، نه یک عدد اسکالر.
از این رو [1] هم آمده است تا نشان دهد این آغاز بردار است.
is.vector(9)
#> [1] TRUE
بیشتر مقادیر در R نوعی بردار هستند!
کنسول R مثال بالا را اینگونه نمایش میدهد:
> squareit(3)
[1] 9
سندهای این برنامهی درسی بیشتر از قراردادی پیروی میکنند که در چند کتاب درسی R به کار رفته است: حذف پرامپت و کامنت کردن نتیجه. این کار کپیپیست کردن نمونههای کد در کنسول و اجرای آنها را آسانتر میکند.