یکی از قابلیتهای برجسته زبان R این است که امکانات متنوعی را برای نمایش دادهها داراست. در این مقاله من به روشهای پایهای برای رسم نمودار اشاره میکنم که در دنیای کسبوکار بیشتر استفاده میشوند. در این مقاله صرفاً به توابع داخلی R برای نمایش داده میپردازم. خواننده باید بداند برای رسم نمودارهای پیشرفتهتر بستههایی مانند ggplot2 توسعه یافتهاند که امکانات وسیعتری را در اختیار میگذارد. رویکرد من در آموزش برنامهنویسی زبان R بیشتر مبتنی بر استفاده از مثال است تا خواننده با اجرای کدها بتواند این زبان را یاد بگیرد. برای اینکه در مثال های این بخش مشکلی نداشته باشید توصیه می کنم سری مقالات قبلی آموزش زبان R برای علوم داده را بخوانید.
در این مقاله، من مثال هایم را عمدتا بر روی دیتا فریم mtcars اجرا کردم. در انتهای مقاله “آموزش زبان R برای علوم داده: مباحث مقدماتی” درباره این دیتا فریم توضیح دادم.
رسم نمودار در R
سادهترین حالت برای رسم نمودار استفاده از تابع plot در R است. در کد زیر، من ابتدا نمودار پراکندگی را برای دو متغیر وزن خودرو (wt) و مسافتی که خودرو برحسب مایل به ازای مصرف یک گالن (mpg) طی میکند، رسم کردم. در خط بعد با استفاده از تابع abline خط رگرسیون را به نمودار اضافه کردم. تابع lm در R برای محاسبه خط رگرسیون بکار میرود. در انتها از تابع title استفاده کردم و یک عنوان به نمودار اضافه کردم. خروجی کار را در شکل-۱ میبینید.
1 2 3 4 | > #Creating a Graph > plot(mtcars$wt, mtcars$mpg) > abline(lm(mtcars$mpg ~ mtcars$wt)) > title("Regresion of MPG on Weight") |
رسم نمودار هیستوگرام (Histogram)
تابع hist برای رسم نمودارهای هیستوگرام بکار میرود. در کد زیر هیستوگرام متغیر mpg را رسم کردم. با استفاده از پارامتر break میتوانید تنظیم کنید تا هیستوگرام دارای چند طبقه (Bin) باشد. با استفاده از پارامتر col رنگ نمودار را بر روی قرمز تنظیم کردم. خروجی کار را در شکل-۲ نشان دادم. توجه کنید تابع هیستوگرام بر اساس فرکانس وقوع (Frequency) یا تعداد حالتهای رخداده رسم شده است.
1 2 | > #Simple Histogram > hist(mtcars$mpg, breaks = 10, col = "Red") |
همانطور که میبینید شکل-۲ ایدئال نیست و میتواند بهتر شود. برای نمونه، میلههای نمودار از حدود محور افقی بیرون زده است. در بخش بعدی با تنظیم پارامترهای تابع hist نمودار بهتری رسم میکنم.
اضافه کردن منحنی تابع توزیع نرمال (Normal Distribution)
در اینجا اگر فرض کنم که متغیر mpg از توزیع نرمال پیروی میکند، میخواهم بر روی هیستوگرام تابع توزیع نرمالی با میانگین و انحراف معیار دادههای موجود رسم و آن را با هیستوگرام مقایسه کنم.
چون تابع توزیع بر اساس چگالی (Density) رسم میشود، برای مقایسه کردن آن با هیستوگرام دادهها لازم است، نمودار هیستوگرام دادهها بهجای فرکانس بر اساس درصد وقوع به نمایش دربیاید. بنابراین پارامتر freq را در تابع hist برابر FALSE قراردادم. از xlim استفاده کردم تا حدود محور افقی را بین صفر و حداکثر مقدار متغیر mpg تنظیم کنم تا مشکل ایجادشده در شکل-۲ بروز نکند. از پارامتر xlab برای تخصیص عنوان محور افقی و از main برای تخصیص عنوان نمودار استفاده کردم.
برای آنکه نمودار نرمال را روی هیستوگرام رسم کنم، متغیر xfit را برداری از اعداد بین صفر تا حداکثر مقدار متغیر mpg تعریف کردم. این بردار ۴۰ عدد را بهصورت یکنواخت در این بازه انتخاب میکند. سپس با استفاده از تابع dnorm مقادیر متناظر آنها را از تابع نرمال به دست آوردم و در متغیر yfit قراردادم. درنهایت از تابع lines استفاده کردم تا منحنی نرمال را به هیستوگرام اضافه کنم. توجه کنید پارامتر lwd ضخامت خط نمودار را تعیین میکند. هر چه این عدد بزرگتر شود، خط ضخیمتر خواهد بود. نتیجه این کد را در شکل-۳ میبینید.
1 2 3 4 5 6 | > #Add a normal curve > x <- mtcars$mpg > hist(x, breaks = 10, freq = F, col = "Red", xlim = c(0, max(x)), xlab = "Miles per Gallon", main = "Histogram with Normal Curve") > xfit <- seq(0, max(x), length = 40) > yfit <- dnorm(xfit, mean = mean(x), sd = sd(x)) > lines(xfit, yfit, col = "Blue",lwd = 2) |
نمودار نقطهای (Dot Plot)
شکل-۴ نمودار توزیع مدلهای مختلف خودرو بر اساس متغیر mpg را در قالب نمودار نقطهای نشان میدهد. از کد زیر برای رسم این نمودار استفاده کردم. در این کد، تابع dotchart را بکار بردم. برچسب محور عمودی بر اساس اسم ردیفها در دیتا فریم mtcars مشخص شده است. به خاطر دارید که اسم ردیفهای این دیتا فریم اسامی مدلهای مختلف خودرو بود. بقیه قسمتهای کد سرراست است.
1 2 | > #Dot plots > dotchart(mtcars$mpg, labels = row.names(mtcars), xlab = "Miles per Gallon", main = "Gas Milage for Car Models") |
همانطور که پیداست نمودار شکل-۴ خیلی گویا نیست. اول اینکه اسامی مدلهای خودرو روی محور عمودی خوانا نیستند. دوم، نمودار برای مخاطب گیجکننده و نامفهوم است.
برای آنکه نمودارهای گویاتر و بهتری رسم کنید، پیشنهاد میکنم مقاله “چگونه ممکن است نمودارها شما را فریب دهند؟” را مطالعه نمایید.
یک روش بهتر برای نمایش همان دادهها، نمودار شکل-۵ است. در این نمودار خودروها بر اساس تعداد سیلندر (متغیر cyl) دستهبندی شدهاند و در هر دسته هم خودروها بر اساس میزان مصرف از بزرگ به کوچک مرتب شدهاند.
برای این منظور من ابتدا دیتا فریم x را بهاینترتیب تعریف کردم که همان دیتا فریم mtcars است اما ردیفهای آن بر اساس مقادیر متغیر mpg با استفاده از تابع order از بزرگ به کوچک مرتب شدهاند. سپس به دیتا فریم x یک ستون با نام color اضافه کردم که بعداً کمک خواهد کرد رنگ دادهها در تابع dotchart از مقادیر آن خوانده شود. این رنگها بر اساس تعداد سیلندر خودرو تخصیص داده میشوند. پارامتر cex سایز برچسبها را پایش میکند (توجه کنید سایز برچسبها نسبت به حالت پیشفرض ۳۰ درصد کمتر شده تا مشکل شکل-۴ پیش نیاید). پارامتر groups تعیین میکند که دادهها چگونه گروهبندی شوند و gcolor رنگ برچسبهای گروهها را مشخص میکند.
1 2 3 4 5 6 | > #Sort by mpg > x <- mtcars[order(mtcars$mpg),] > x$color[x$cyl == 4] <- "red" > x$color[x$cyl == 6] <- "blue" > x$color[x$cyl == 8] <-" dark green" > dotchart(x$mpg, labels = row.names(x), cex=0.7, groups= factor(x$cyl), main = "Gas Milage for Car Models Grouped by Cylinder", xlab = "Miles per Gallon", gcolor = "black", color = x$color) |
نمودار ستونی (Column Chart)
اگر بخواهم مشابه شکل-۶ توزیع خودروها را بر اساس تعداد دندههایشان رسم کنم، بهتر است آن را در قالب نمودار ستونی نشان دهم. برای این منظور ابتدا لازم است بدانم در هر گروه چند خودرو وجود دارد. تابع table فراوانی خودروهای هر گروه را نشان میدهد. خروجی تابع table را در متغیر counts ذخیره کردم. همانطور که میبینید کلاس این متغیر جدول (Table) است و تعداد خودروهای سه، چهار و پنج دنده را در دادههای mtcars مشخص میکند. گام بعدی استفاده از تابع barplot برای رسم این جدول است. اگر بخواهید این نمودار را به شکل افقی رسم کنید (شکل-۷)، کافی است در تابع barplot پارامتر horiz را معادل TRUE قرار دهید.
1 2 3 4 5 6 7 8 9 | > #Bar plots > counts <- table(mtcars$gear) > counts 3 4 5 15 12 5 > class(counts) [1] "table" > barplot(counts, main = "Car Distribution", xlab = "# of Gears", ylim = c(0, 20)) > barplot(counts, main = "Car Distribution", horiz = TRUE, names.arg = c("3 Gears", "4 Gears", "5 Gears"), xlim = c(0,20)) |
نمودار ستونی انبارهای (Stacked Column Chart)
نمودار شکل-۸ نمونهای از نمودارهای ستونی انبارهای را نشان میدهد. در این نمودار علاوه بر اینکه مشخص شده است در هر گروه برحسب تعداد دنده، چند خودرو وجود دارد، نشان میدهد در هر گروه فراوانی خودروها برحسب اینکه نوع موتورشان V-shape هست یا نیست (۱ یا ۰) چگونه است.
برای رسم این نمودار مشابه قبل ابتدا جدول فراوانی را در متغیر counts قراردادم، با این تفاوت که جدول فراوانی را بر اساس دو متغیر vs و gear تعریف کردم. بهاینترتیب دستهبندی اصلی جدول بر اساس متغیر gear و دستهبندی فرعی بر اساس متغیر vs ایجاد شده است (اینکه کدام متغیر را اول بگذارید و کدام را دوم نحوه آرایش جدول را تعیین میکند). نکته دیگر اینکه پارامتر legend را طوری تنظیم کردم تا راهنمای نمودار را به نمایش دربیاورد. بقیه قسمتهای کد سرراست است.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | > #Stacked bar plot with colors and legend > head(mtcars) mpg cyl disp hp drat wt qsec vs am gear carb Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1 > counts <- table(mtcars$vs, mtcars$gear) > counts 3 4 5 0 12 2 4 1 3 10 1 > barplot(counts, main = "Car Distribution by Gears and VS", xlab = "# of Gears", ylim = c(0, 20), col = c("dark blue", "red"), + legend = rownames(counts)) |
نمودار ستونی گروهی (Grouped Column Chart)
اگر بخواهم بهجای حالت انبارهای، نمودار شکل-۸ را گروهی به نمایش دربیاورم، از کد زیر استفاده میکنم:
1 2 3 4 | > #Grouped bar plot > counts <- table(mtcars$vs, mtcars$gear) > barplot(counts, main = "Car Distribution by Gears and VS", xlab = "# of Gears", ylim = c(0, 15), col = c("dark blue", "red"), + legend = rownames(counts), beside = T) |
نتیجه را در شکل-۹ نشان دادم.
نمودار دایرهای (Pie Charts)
برای مثال نمودار دایرهای، ابتدا یک سری داده ایجاد کردم و آنها را در بردار numbers قراردادم. برچسب متناظر این دادهها را در بردارcategory تخصیص دادم. نمودار شکل-۱۰ نمودار دایرهای این دادهها را بر اساس فراوانی نشان میدهد. تابع pie برای رسم نمودار دایرهای استفاده میشود:
1 2 3 4 | > #Simple pie chart > numbers <- c(50, 70, 20, 30, 80) > category <- c("A", "B", "C", "D", "E") > pie(numbers, labels = category, main = "Pie Chart") |
با استفاده از کد زیر نمودار شکل بالا را کمی اصلاح کردم (شکل-۱۱). مهمترین تغییر این است که اعداد بر اساس درصد به نمایش درآمدهاند و برچسبها هم گویاتر شدهاند.
1 2 3 4 5 6 7 | > pct <- round(numbers / sum(numbers) * 100) > pct [1] 20 28 8 12 32 > l <- paste(category, ":", pct, "%") > l [1] "A : 20 %" "B : 28 %" "C : 8 %" "D : 12 %" "E : 32 %" > pie(pct, labels = l, main = "Pie Chart", col = rainbow(length(l))) |
نمودار جعبهای (Box Plot)
رسم نمودار جعبهای خیلی سرراست است. کافی است از تابع boxplot استفاده و مشخص کنیم با چه فرمولی میخواهیم نمودار جعبهای را رسم کنیم. در کد زیر منبع دادهها، دیتا فریم mtcars است و رابطه mpg ~ cyl نشان میدهد متغیر mpg را برحسب cyl رسم کردهام (شکل-۱۲):
1 2 3 | > #Box plot > boxplot(mpg ~ cyl, data = mtcars, main = "Car Milage Data", + xlab = "Number of Cylinders", ylab = "Miles Per Gallon") |
چنین نموداری میتواند رابطه بین یک متغیر پیوسته (mpg – به ازای هر گالن بنزین، خودرو چند مایل طی میکند) با یک متغیر رستهای (cyl – تعداد سیلندر خودرو) را بهخوبی نشان دهد. در این مثال به نظر میرسد هر چه تعداد سیلندر خودرو افزایش یابد، mpg بهطورکلی کاهش مییابد. بهعبارتدیگر خودروهای با سیلندر پایینتر، درمجموع کارایی مصرف سوخت بهتری دارند.
افزودن میانگین به نمودار جعبهای
همانطور که مشخص است در نمودار جعبهای بهصورت پیشفرض میانگین دادهها در نمودار به نمایش گذاشته نمیشود. بخصوص در مورد دادههایی که چولگی دارند، خوب است در نمودار جعبهای علاوه بر میانه دادهها (خط وسط جعبه)، میانگین هم به نمایش داده شود. در کد زیر، من با تابع tapply در R میانگین دادهها را در ستون mpg بر اساس تعداد سیلندر خودرو محاسبه کردم. برای مثال، نتایج زیر نشان میدهد میانگین mpg برای خودروهای ۴ سیلندر ۲۶٫۷ است.
1 2 3 4 5 | > mean_data = tapply(mtcars$mpg, mtcars$cyl, mean) > mean_data 4 6 8 26.66364 19.74286 15.10000 |
حال که میانگین mpg در گروههای مختلف را دارم، میتوانم از تابع points برای نمایش میانگین روی نمودار قبلی با نقاط قرمزرنگ استفاده کنم. در تابع points کافی است مختصات نقاط میانگین در فضای دکارتی را مشخص کنیم. خروجی در شکل-۱۳ آمده است.
1 2 3 4 5 | > #Box Plot with Mean > boxplot(mpg ~ cyl,data = mtcars, main = "Car Milage Data", + xlab = "Number of Cylinders", ylab = "Miles Per Gallon") > mean_data = tapply(mtcars$mpg, mtcars$cyl, mean) > points(1 : 3, mean_data, col = 'red') |
نمودار پلهای (Step Plot)
برای رسم نمودار پلهای میتوان از همان تابع lines که در بالا معرفی شد، استفاده کرد. برای این منظور من دادههایی را در x و y شبیهسازی کردم که ماهیت پلهای دارند. بردار x بیست عدد بین ۰ تا ۵ است که با فاصله یکسان از یکدیگر هستند و y به ازای هر پنج عدد در x، یک مقدار ثابت است. من ابتدا x و y را در قالب نمودار پراکندگی رسم کردم و سپس برای رسم تابع پلهای از تابع lines استفاده کردم. در تابع lines کافی است type را معادل s قرار دهید. بقیه موارد سرراست است.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | > x <- seq(0, 5, length.out = 20) > x [1] 0.0000000 0.2631579 0.5263158 0.7894737 [5] 1.0526316 1.3157895 1.5789474 1.8421053 [9] 2.1052632 2.3684211 2.6315789 2.8947368 [13] 3.1578947 3.4210526 3.6842105 3.9473684 [17] 4.2105263 4.4736842 4.7368421 5.0000000 > y <- c(rep(0.5, 5), + rep(1, 5), + rep(1.5, 5), + rep(2, 5)) > y [1] 0.5 0.5 0.5 0.5 0.5 1.0 1.0 1.0 1.0 1.0 1.5 1.5 [13] 1.5 1.5 1.5 2.0 2.0 2.0 2.0 2.0 > plot(x, y) > lines(x, y, type = 's', col = 'red', lwd = 2) |
مقالات آموزش زبان R در آنالیکا
آموزش زبان R برای علوم داده: مباحث مقدماتی
آموزش زبان R برای علوم داده: خواندن و نوشتن دادهها
آموزش زبان R برای علوم داده: عبارات شرطی و حلقهها
ممنون از مطالبی که برای آموزش R گذاشته اید.
سلام
خیلی ممنون از مطالبی که گذاشتید. خلاصه و مفید بودش.
خیلی ممنون میشم این سلسله مطالب ادامه داشته باشه و مطالب پیشرفته تری بذارید.
با تشکر
با عرض سلام
می خواستم ازتون سوال کنم که برای تعریف ستون رنگ براساس تعداد سیلندر خودروها، امکان نوشتن دستور شرطی براساس If , Else هم می باشد یا خیر.
با تشکر از مطالب بسیار آموزنده شما
کد quantiles میشه اموزش بدین ؟؟؟
سلام و وقت بخیر
به مقاله زیر در آنالیکا مراجعه کنید:
https://analica.ir/quantile-r-python/
برا اینکه روی نمودتر هیستوگرام یکی از داده های رو مشخص کنیم باید چه کدی بزنیم
سلام و خسته نباشید آموزش ها مفیده اما R یک نرم افزار نیست یک زبان برنامه نویسی میباشد که از اون توی حوزه های تحلیل داده و غیره استفاده میشود.
بهتره که اون و زبان برنامه نویسی خطاب کنیم.
سلام ممنونم از توصیحاتتون عالی بود فقط میشه لطف کنین نمودار پراکندگی هم توضیح بدین
دستور نمودار پراکندگی چیه؟ممنون میشم جواب بدین ضروریه کارم
سلام و وقت بخیر
اولین نمودار رسم شده در مقاله، نمودار پراکندگی است با تابع plot به راحتی می توانید نمودار پراکندگی را رسم کنید.
با سلام
لطفا برای کوچک کردن سایز برچسب گذاری های روی نمودارها چ دستوری لازم است؟
میشه در نرم افزار R روی باکس پلات مقدار میانگین را مشخص کرد اگه راهی داره لطفا بذارین
با سلام و وقت بخیر
به مقاله اضافه شد.
سلام چطور میشه در R نمودار پلکانی نصب کرد؟
لطفا راهنمایی کنید ممنون
با سلام و وقت بخیر
به مقاله اضافه شد.
سلام میشه دستور نمودار چندبر فراوانی را بگید