تبدیل و پاکسازی داده‌ ها با کتابخانه dplyr و tidyr در R — راهنمای کاربردی

۵۸۵ بازدید
آخرین به‌روزرسانی: ۰۶ خرداد ۱۴۰۲
زمان مطالعه: ۱۵ دقیقه
تبدیل و پاکسازی داده‌ ها با کتابخانه dplyr و tidyr در R — راهنمای کاربردی

در بیشتر زمینه‌های «تحلیل داده‌ها» (Data Analysis)، کارهای اولیه به سه بخش تقسیم می‌شوند. بخش اول «استخراج» (Extraction) داده‌ها است. بخش دوم «تبدیل» (Transformation) و «پاکسازی» (Cleaning) و بخش سوم نیز «بصری سازی» یا «نمایش» (Visualization) داده‌ها نامیده می‌شود. توابع موجود در کتابخانه dplyr و tidyr در زبان برنامه‌نویسی R، به منظور انجام بخش دوم یعنی تبدیل و پاکسازی داده‌ها به کار گرفته می‌شوند. در این نوشتار توابعی از کتابخانه dplyr و tidyr را مورد بررسی قرار می دهیم که عمل «ادغام» (Merge) و همچنین پاکسازی داده‌ها را انجام می‌دهند. برای اجرای کدهای نوشته شده در R از پوسته Rstudio کمک می‌گیریم.

تبدیل و پاکسازی داده‌ها با کتابخانه dplyr و tidyr در R

یکی از مشکلاتی که یک تحلیل‌گر داده (Data Scientist) با آن مواجه است، تبدیل (Transformation) بر روی داده‌ها است زیرا آن‌ها با قالب و شکلی که انتظار دارد، جمع‌آوری نشده‌اند. یک تحلیل‌گر داده باید نیمی از وقت خود را صرف پاکسازی و تبدیل کردن داده بکند.

به این ترتیب مشخص است که این وظایف یکی از حساس‌ترین قسمت‌های کار تحلیل داده‌ها است. اگر بخش مربوط به تبدیل و پاکسازی به درستی، دقت و بطور کامل صورت نگرفته باشد، مدلی که در مراحل بعدی تولید خواهد شد، مناسب نخواهد بود.

پاکسازی داده‌ها

از کتابخانه‌های محبوب در زبان برنامه‌نویسی R، کتابخانه dplyr و tidyr است که بعضی از توابع آن وظایف تبدیل و پاکسازی داده‌ها را انجام می‌دهند. در این متن به بررسی توابع خانواده join از کتابخانه dplyr و همچنین توابع gather, spread, separate و unite از کتابخانه tidyr می‌پردازیم.

ادغام داده‌ها در کتابخانه dplyr

کتابخانه dplyr، توابعی دارد که عمل ترکیب و تبدیل «مجموعه داده» (Dataset) را در R به سادگی و راحتی انجام می‌دهند. ممکن است منابع اطلاعاتی ما مختلف باشند و نیاز است که در یک نقطه آن‌ها را با یکدیگر ادغام کنیم. در این کتابخانه چهار روش مختلف برای ادغام منابع اطلاعاتی یا مجموعه‌های داده درست به مانند SQL وجود دارد. البته بعضی از توابع خانواده join مخصوص فیلتر کردن داده‌ها هستند که به آن‌ها نیز خواهیم پرداخت.

  • تابع ادغام از چپ - $$left\_join()$$
  • تابع ادغام از راست -  $$right\_join()$$
  • تابع ادغام داخلی - $$inner\_join()$$
  • تابع ادغام کامل - $$full\_join()$$
  • تابع فیلتر - $$semi\_join()$$
  • تابع فیلتر - $$anti\_join()$$

در ادامه، براساس یک مثال به بررسی این توابع می‌پردازیم. ابتدا دو مجموعه داده می‌سازیم. جدولی با نام Table 1 که شامل دو فیلد (متغیر) ID و y است. به همین ترتیب نیز جدولی با نام Table 2 نیز ایجاد کرده‌ایم که شامل متغیر ID و z است. در چنین حالتی، احتیاج به یک فیلد یا متغیر با مقدارهای مشترک در هر دو جدول داریم تا بتوانیم سطرهای متناظر را تشخیص و در عمل ادغام دخیل کنیم. در اینجا متغیر ID همان متغیر مشترک است که از این به بعد به آن متغیر کلید (key Variable) می‌گوییم.

در تصویر زیر اطلاعات ثبت شده در دو جدول Table 1 و Table 2‌دیده می‌شوند. مشخص است که مقدارهای مربوط به متغیر کلید (ID) برای سطرهای مرتبط یکسان هستند.

dplyr function 1

کدهای زیر به منظور بارگذاری کتابخانه dplyr و همچنین ایجاد جدول‌ها نوشته شده‌اند.

1library(dplyr)
2df_primary <- tribble(
3  ~ID, ~y,
4  "A", 5,
5  "B", 5,
6  "C", 8,
7  "D", 0,
8  "F", 9)
9df_secondary <- tribble(
10  ~ID, ~z,
11  "A", 30,
12  "B", 21,
13  "C", 22,
14  "D", 25,
15  "E", 29)

با اجرای این کد دو جدول به نام‌های $$df\_primary$$ و $$df\_secondry$$ ایجاد می‌شود که متغیر کلید آن دارای مقدارهای متنی (chr) از A تا F و متغیر دومی نیز مقدارهای عددی با ممیز شناور (dbl) هستند.

1> df_primary
2# A tibble: 5 x 2
3  ID        y
4  <chr> <dbl>
51 A         5
62 B         5
73 C         8
84 D         0
95 F         9
10> df_secondary
11# A tibble: 5 x 2
12  ID        z
13  <chr> <dbl>
141 A        30
152 B        21
163 C        22
174 D        25
185 E        29
19>

توجه دارید که در جدول اول سطری با ID برابر با F وجود دارد که در جدول دوم چنین سطری نیست. همچنین در جدول دوم نیز سطری با ID برابر با E هست که در جدول اول وجود ندارد.

ادغام از چپ - $$left\_join()$$

یکی از معمول‌ترین روش‌های ادغام دو مجموعه داده، استفاده از تابع $$left\_join()$$ است. در این حالت براساس تصویری که در ادامه دیده می‌شود، با استفاده از متغیر کلید، سطرهای متناظر شناسایی شده و ستون‌های هر دو جدول براساس سطرهای متناظر در کنار یکدیگر قرار می‌گیرند.

left join

مشخص است که براساس متغیر ID مقدارهای سطرهای A,B,C,D در هر دو جدول مشترک هستند. بنابراین در جدول Table 3 حضور دارند. ولی از آنجایی که عمل ادغام از چپ است، جدول Table 1‌ اولویت دارد در نتیجه سطر F نیز اضافه شده ولی سطر E از جدول دوم اجازه ورود به جدول Table 3 را ندارد.

از آنجایی که برای سطر F در جدول دوم Table 2 مقداری برای متغیر z وجود ندارد، در جدول Table 3 مقدار NA برای متغیر z در سطر F ظاهر شده است. به این معنی که مقدار متغیر z برای سطر F ناموجود (Not Available) است.

نکته: اگر مقدار متغیری در مجموعه داده NA باشد، نرم‌افزار R آن را به عنوان داده ناموجود یا گمشده (Missing) در نظر می‌گیرد.

برای اجرای چنین ادغامی، از شکل دستوری زیر برای تابع $$left\_join()$$ استفاده می‌کنیم.

1left_join(df_primary, df_secondary, by ='ID')

مشخص است که اولین پارامتر (df_primary)، جدول اصلی و دومین پارامتر (df_secondary) نیز جدولی را مشخص می‌کند که باید با جدول اصلی ادغام شود. پارامتر سوم $$by='ID'$$ نیز مشخص می‌کند که متغیر کلید در بین هر دو جدول ID‌ در نظر گرفته شده است. از آنجایی که ادغام از چپ صورت گرفته، در جدول جدید (Table 3) سطرهای جدول اول (Table 1) حفظ شده و فقط ستون z براساس سطرهای متناظر، اضافه شده است. خروجی به صورت زیر در خواهد آمد.

1> left_join(df_primary, df_secondary, by ='ID')
2# A tibble: 5 x 3
3  ID        y     z
4  <chr> <dbl> <dbl>
51 A         5    30
62 B         5    21
73 C         8    22
84 D         0    25
95 F         9    NA
10>

ادغام از راست - $$right\_join()$$

روش دیگر برای ادغام دو منبع اطلاعاتی، ادغام از راست است. به توجه به مفهوم ادغام از چپ، احتمالا روش ادغام از راست را نیز به راحتی درک خواهید کرد. تنها تفاوتی که در بین ادغام از چپ با ادغام از راست دو جدول مثال ما دیده می‌شود، وجود سطری با ID برابر با E است.

از انجایی که ادغام از راست صورت گرفته، اولویت با جدول دوم است. در نتیجه ستون‌های مختلف این دو جدول براساس مقدارهای متغیر کلید شناسایی شده و در کنار یکدیگر قرار می‌گیرند و همچنین سطری از جدول دوم که در جدول اول دارای مقدار مشترکی نیست در جدول Table 3 دیده شده ولی مقدار متغیر y برایش به صورت NA ظاهر می‌شود. تصویر زیر شیوه ادغام این دو جدول را به خوبی نشان می‌دهد.

right join

کد دستوری برای اجرای این عمل به صورت زیر است.

1right_join(df_primary, df_secondary, by = 'ID')

مشخص است که پارامترها درست به مانند پارامترهای $$left\_join()$$ است،  ولی نحوه عمل تابع $$right_\_join()$$ ادغام جدول معرفی شده در پارامتر اول به جدول مشخص شده در پارامتر دوم است. بطوری که اولویت با جدول دوم است. پارامتر by نیز درست به مانند قبل، متغیر مشترک در هر دو جدول را معرفی می‌کند. خروجی به صورت زیر خواهد بود.

1> right_join(df_primary, df_secondary, by = 'ID')
2# A tibble: 5 x 3
3  ID        y     z
4  <chr> <dbl> <dbl>
51 A         5    30
62 B         5    21
73 C         8    22
84 D         0    25
95 E        NA    29
10>

همانظور که دیده می‌شود، در جدول ایجاد شده، سطر F وجود ندارد و همچنین در سطر مربوط به مقدار متغیر ID=E برای متغیر y مقدار NA ثبت شده است.

نکته: ترتیب قرارگیری متغیرها پس از ادغام، همان ترتیبی است که پارامترهای تابع نشان می‌دهد. یعنی ابتدا متغیرهای جدول df_primary و سپس متغیرهای جدول df_secondary قرار می‌گیرند. اگر می‌خواهید ترتیب قرارگیری متغیرها برعکس باشد باید جای پارامتر اول و دوم را تغییر دهید.

ادغام داخلی - $$inner\_join()$$

اگر می‌خواهید فقط سطرهای مشترک از دو جدول با یکدیگر ادغام شوند از تابع $$inner\_join()$$ استفاده کنید. با این کار در جدول جدید، سطرهایی که دارای مقدار مشترک در متغیر کلید هستند ظاهر می‌شوند. نتیجه این کار جدولی است که دارای هیچ مقدار گمشده‌ای نیست. تصویر زیر به درک شیوه ادغام با تابع $$inner\_join()$$ یاری می‌رساند.

inner join

همانطور که دیده می‌شود، در جدول Table 3 هیج سطری با مقدار NA دیده نمی‌شود. همچنین فقط سطرهایی از دو جدول Table 1 و Table 2 با یکدیگر ادغام شده‌اند که در متغیر کلید دارای مقدار مشترک باشند. کد دستوری برای اجرای چنین ادغامی به صورت زیر است.

1inner_join(df_primary, df_secondary, by ='ID')

پارامترهای این تابع نیز درست به مانند پارامترهای توابع قبلی است. خروجی این دستور به صورت زیر خواهد بود.

1> inner_join(df_primary, df_secondary, by ='ID')
2# A tibble: 4 x 3
3  ID        y     z
4  <chr> <dbl> <dbl>
51 A         5    30
62 B         5    21
73 C         8    22
84 D         0    25

ادغام کامل - $$full\_join()$$

نوع دیگری که برای ادغام دو مجموعه داده باقی می‌ماند، روش ادغام کامل است که به کمک تابع  $$full\_join()$$ صورت می‌پذیرد. اگر می‌خواهید همه سطرهای مشترک و غیر مشتکر از دو جدول را در کنار یکدیگر ببینید از تابع $$full\_join()$$ استفاده کنید. به این ترتیب اگر در بین دو جدول، سطرهایی غیر مشترک وجود داشته باشند، داده‌های گمشده با مقدار NA  جایگزین خواهند شد. تصویر زیر به بررسی وضعیت چنین ادغامی پرداخته است.

full join

برای اجرای این نوع ادغام از کد دستوری زیر استفاده می‌کنیم.

1full_join(df_primary, df_secondary, by = 'ID')

باز هم دیده می‌شود که پارامترهای این تابع درست به مانند هم خانواده‌هایش است. خروجی این کد در ادامه دیده می‌شود.

1> full_join(df_primary, df_secondary, by = 'ID')
2# A tibble: 6 x 3
3  ID        y     z
4  <chr> <dbl> <dbl>
51 A         5    30
62 B         5    21
73 C         8    22
84 D         0    25
95 F         9    NA
106 E        NA    29
11>

نکته: در خانواده توابع join، اگر جای پارامترهای اول و دوم را تعویض کنیم، جای قرارگیری متغیرها تغییر خواهد کرد. زیرا پارامتر اول جدول اصلی و پارامتر دوم جدولی است که باید به جدول اول اضافه شود. در زیر جای این پارامترها تغییر کرده و نتیجه قابل مشاهده است.

1> full_join(df_secondary, df_primary, by ='ID')
2# A tibble: 6 x 3
3  ID        z     y
4  <chr> <dbl> <dbl>
51 A        30     5
62 B        21     5
73 C        22     8
84 D        25     0
95 E        29    NA
106 F        NA     9
11>

فیلتر کردن با توابع $$semi\_join()$$ و $$anti\_join()$$

فرض کنید از جدول Table 1‌ می‌خواهید فقط مشاهداتی را جدا کنید که دارای مقدار مشترک با جدول Table 2 هستند. با تابع $$semi\_join()$$ این کار به راحتی صورت می‌گیرد. کافی است برای مثال براساس مجموعه داده‌های df_primary و df_secondary به صورت زیر کد نویسی کنیم.

1semi_join(df_primary,df_secondary,by='ID')

مشخص است که پارامترها درست به مانند قبل است، با این تفاوت که این تابع عمل ادغام را انجام نمی‌دهد و فقط سطرها یا مشاهداتی از جدول اولیه (df_primary) را نشان می‌دهد که دارای مقدار مشترک براساس متغیر ID با جدول ثانویه (df_secondary) هستند. خروجی به صورت زیر خواهد بود.

1> semi_join(df_primary,df_secondary,by='ID')
2# A tibble: 4 x 2
3  ID        y
4  <chr> <dbl>
51 A         5
62 B         5
73 C         8
84 D         0

همچنین اگر بخواهیم فقط سطرها یا مشاهداتی را از جدول اولیه نشان دهیم که دارای مقدار مشترکی برحسب ID با جدول ثانویه نیستند، از تابع $$anti\_join()$$ استفاده خواهیم کرد. کد زیر نیز به این منظور تهیه شده است.

1anti_join(df_primary,df_secondary,by='ID')

به وضوح مشخص است که تنها مشاهده‌ای F است که از جدول اول، دارای مقدار مشترک با جدول دوم برحسب متغیر ID نیست. در نتیجه این سطر ID=F مشاهده خواهد شد.

1> anti_join(df_primary,df_secondary,by='ID')
2# A tibble: 1 x 2
3  ID        y
4  <chr> <dbl>
51 F         9
6>

نکته: اگر می‌خواهید سطرهایی از جدول df_secondary را مشاهده کنید که با جدول df_primary مشترک نیستند، کافی است جای پارامتر اول و دوم را در دستور قبلی عوض کنید. نتیجه دستور و خروجی به صورت زیر خواهد بود و فقط سطر ID=E مشاهده خواهد شد.

1> anti_join(df_secondary,df_primary,by='ID')
2# A tibble: 1 x 2
3  ID        z
4  <chr> <dbl>
51 E        29
6>

استفاده از چندین متغیر کلید

ممکن است برای ایجاد ارتباط بین دو جدول بیش از یک متغیر مبنا قرار گیرد. در این حالت برای مثال دو متغیر وجود دارد که بین دو جدول مشترک است. حال می‌خواهیم دو جدول را به کمک این دو متغیر ادغام کنیم. در تصویر زیر نحوه ادغام دو جدول نمایش داده شده است.

multiple key variable join

همانطور که در تصویر مشخص است، دو جدول دیده می‌شود که اولی (Table 1) شامل لیست مشتریانی است که از یک فروشگاه خرید کرده‌اند. متغیرهای ID, year, item نیز به ترتیب نشانگر کد مشتری، سال خرید و تعداد خریدها هستند. در جدول دوم (Table 2) نیز مشخصات مشترک مانند ID, year وجود دارد. همچنین میزان خرید مشتری نیز در متغیر price آورده شده است. قرار است این دو جدول با یکدیگر ادغام شوند تا تعداد و میزان خرید مشتریان در کنار یکدیگر قرار گیرند.

این اطلاعات توسط کد زیر در دو مجموعه داده df_primary و df_secondary قرار گرفته است.

1df_primary <- tribble(
2  ~ID, ~year, ~items,
3  "A", 2015,3,
4  "A", 2016,7,
5  "A", 2017,6,
6  "B", 2015,4,
7  "B", 2016,8,
8  "B", 2017,7,
9  "C", 2015,4,
10  "C", 2016,6,
11  "C", 2017,6)
12df_secondary <- tribble(
13  ~ID, ~year, ~prices,
14  "A", 2015,9,
15  "A", 2016,8,
16  "A", 2017,12,
17  "B", 2015,13,
18  "B", 2016,14,
19  "B", 2017,6,
20  "C", 2015,15,
21  "C", 2016,15,
22  "C", 2017,13)

برای ادغام از چپ این دو جدول از کد دستوری زیر استفاده می‌کنیم. مشخص است که برای معرفی دو متغیر به عنوان متغیر کلید، نام دو متغیر را در پارامتر by قرار داده‌ایم. کد و خروجی در زیر دیده می‌شود.

1> left_join(df_primary, df_secondary, by = c('ID', 'year'))
2# A tibble: 9 x 4
3  ID     year items prices
4  <chr> <dbl> <dbl>  <dbl>
51 A      2015     3      9
62 A      2016     7      8
73 A      2017     6     12
84 B      2015     4     13
95 B      2016     8     14
106 B      2017     7      6
117 C      2015     4     15
128 C      2016     6     15
139 C      2017     6     13
14>

توابع مرتبط با پاکسازی داده‌ها

یکی دیگر از کتابخانه‌های مطرح برای عملیات پاکسازی داده (Data Cleaning) در R، کتابخانه $$tidyr()$$ است.

در ادامه به توابع از این کتابخانه اشاره خواهیم کرد که در انجام پاکسازی داده موثر هستند.

  • تابع جمع‌آوری $$gather()$$
  • تایع گسترش $$spread()$$
  • تابع تفکیک $$separate()$$
  • تابع تجمیع $$unite()$$

نکته: اگر این کتابخانه بر روی نرم‌افزار R، نصب نشده باشد، می‌توانید از دستور زیر برای نصب آن اقدام کنید. البته این کار را برای کتابخانه dplyr نیز می‌توانید انجام دهید. برای این کار باید به اینترنت متصل باشد.

1 install.packages("tidyr")

تابع $$gather()$$

گاهی نیاز است که شیوه نگهداری اطلاعات در یک مجموعه داده تغییر کند. فرض کنید اطلاعات به صورت تجمیعی در یک جدول مانند تصویر زیر قرار گرفته‌اند. برای انجام تحلیل روی داده‌ها احتیاج داریم که ستون‌های time‌ و growth را در یک متغیرهای جداگانه ثبت کنیم. تابع $$gather()$$ این کار به خوبی انجام می‌دهد.

gather function

کدهای زیر به منظور ایجاد چنین مجموعه داده‌های نوشته شده‌اند. متغیر country کد کشور و q1_2017 تا q4_2017 نیز نشانگر فصل‌های مختلف سال ۲۰۱۷ هستند. در داخل جدول زیر متغیر میزان رشد در هر مقطع و هر کشور ثبت شده است.

1messy <- data.frame(
2  country = c("A", "B", "C"),
3  q1_2017 = c(0.03, 0.05, 0.01),
4  q2_2017 = c(0.05, 0.07, 0.02),
5  q3_2017 = c(0.04, 0.05, 0.01),
6  q4_2017 = c(0.03, 0.02, 0.04))
7messy

این مقدارهای در «چارچوب داده» (data.frame) به نام messy ثبت شده‌ است. خروجی این دستورات به صورت زیر در خواهد آمد.

1> messy
2  country q1_2017 q2_2017 q3_2017 q4_2017
31       A    0.03    0.05    0.04    0.03
42       B    0.05    0.07    0.05    0.02
53       C    0.01    0.02    0.01    0.04
6>

حال می‌خواهیم مانند تصویر قبلی، مجموعه داده را به صورتی درآوریم که هر متغیرها بخصوص مقدارهای درون جدول به صورت یک متغیر جداگانه ثبت و نگهداری شوند. کد دستوری زیر به این منظور نوشته شده است. همانطور که مشخص است تابع $$gather()$$ از کتابخانه $$tidyr$$ به کار رفته است.

1# Reshape the data
2tidier = gather(messy, quarter, growth, q1_2017:q4_2017)
3tidier

در ادامه به بررسی بعضی از پارامترهای این دستور پرداخته‌ایم. هر یک از این پارامترها در جدول زیر معرفی شده‌اند.

1gather(data, key, value, na.rm = FALSE)
2Arguments:
3-data: The data frame used to reshape the dataset 
4-key: Name of the new column created
5-value: Select the columns used to fill the key column
6-na.rm: Remove missing values. FALSE by default
پارامترعملکرد
dataچارچوب داده که باید تغییر کند.
keyنام ستون یا ستون‌هایی که باید ایجاد شود.
value نام ستونی از چارچوب داده که باید ستون‌های جدید را مقدار دهی کند.
na.rmمقدار منطقی به منظور حذف داده‌های گمشده (پیش‌فرض FALSE)

همانطور که مشخص است پارامتر اول این دستور مجموعه داده‌ای است که باید تغییر کند. همچنین پارامترهای دوم و سوم نیز بیانگر متغیرهایی است که باید ایجاد شوند. پارامتر آخر نیز مجموعه مقدارهایی است که باید پارامترهای دوم و سوم از آن استخراج شوند. در نتیجه خروجی دستور بالا به صورت زیر در خواهد آمد.

1> tidier
2   country quarter growth
31        A q1_2017   0.03
42        B q1_2017   0.05
53        C q1_2017   0.01
64        A q2_2017   0.05
75        B q2_2017   0.07
86        C q2_2017   0.02
97        A q3_2017   0.04
108        B q3_2017   0.05
119        C q3_2017   0.01
1210       A q4_2017   0.03
1311       B q4_2017   0.02
1412       C q4_2017   0.04

به این ترتیب به کمک تابع $$gather()$$ یک مجموعه داده جدید براساس اطلاعات قبلی ساخته شد که در آن متغیرهای رشد (growth) و فصل (quarter) موجود بوده و مقدار دهی شده‌اند. همانطور که مشخص است به منظور ایجاد این متغیرها، مقدارهای متغیر country تکرار شده‌اند تا یکپارچگی داده‌ها از بین نرود.

تابع $$spread()$$

توابع $$gather()$$ و $$spread()$$ عکس یکدیگر عمل می‌کنند. بنابراین اگر می‌خواهید مجموعه داده را به صورت تجمیعی درآورید و ستون‌ها گسترش یابند، از تابع $$spread()$$‌ استفاده کنید. پارامترهای این تابع نیز به مانند پارامترهای تابع $$gather()$$‌ است. در ادامه به معرفی بعضی از این پارامترها پرداخته‌ایم.

1spread(data, key, value)
2arguments: 
3data: The data frame used to reshape the dataset 
4key: Column to reshape long to wide
5value: Rows used to fill the new column
پارامترعملکرد
dataمجموعه داده‌ای که باید تغییر شکل یابد.
keyمتغیری که مقدارش به منظور نام‌گذاری ستون‌ها به کار می‌رود.
valueمقدارهایی که باید به منظور تشکیل جدول تجمیعی جدید درون جدول به کار روند.

برای مثال فرض کنید که چارچوب داده tidier که در مثال قبل ایجاد شد را می‌خواهیم به صورت تجمیعی درآوریم بطوری که مقدارهای متغیر quarter در سطرهای جدول و مقدارهای growth نیز درون جدول جای گیرند. کد زیر به این منظور تهیه شده است.

1messy_again=spread(tidier,quarter, growth)
2messy_again

با اجرای این کد، خروجی به صورت زیر خواهد بود.

1> messy_again=spread(tidier,quarter, growth)
2> messy_again
3  country q1_2017 q2_2017 q3_2017 q4_2017
41       A    0.03    0.05    0.04    0.03
52       B    0.05    0.07    0.05    0.02
63       C    0.01    0.02    0.01    0.04
7>

مشخص است که چارچوب داده messy_again با messy یکی است.

تابع $$separate()$$

فرض کنید مقدارهای یک متغیر یا ستون را باید به دو ستون یا دو متغیر مجزا تفکیک کنیم. همانطور که به یاد دارید در چارچوب اطلاعاتی tidier، متغیر quarter شامل سال و فصل بود. مثلا یکی از مقدارهای این متغیر به صورت $$q1\_2017$$ نوشته شده است. اگر بخواهیم سال را از فصل جدا کنیم، تابع $$separate()$$ انتخاب خوب و مناسبی برای انجام این کار است.

پارامترهای این تابع به صورت زیر است. جدولی که در ادامه دیده می‌شود، به معرفی این پارامترها پرداخته است.

1separate(data, col, into, sep= "", remove = TRUE)
2arguments:
3-data: The data frame used to reshape the dataset 
4-col: The column to split
5-into: The name of the new variables
6-sep: Indicates the symbol used that separates the variable, i.e.:  "-", "_", "&"
7-remove: Remove the old column. By default sets to TRUE.
پارامترعملکرد
dataچارچوب داده
colستونی که باید تفکیک شود
intoنام متغیرهای جدید
sepعلامت جدا کننده برای مقدارهای متغیر col
removeمقدار منطقی به منظور حذف ستون col از مجموعه داده- پیش‌فرض TRUE

برای جداسازی متغیر quarter و ایجاد دو متغیر Qrt و Year برای ثبت فصل و سال در چارچوب داده tidier از کد زیر استفاده می‌کنیم. مشخص است که علامت جداکننده در اینجا "_"‌ است.

1separate_tidier=separate(tidier,quarter,c("Qrt","Year"),sep="_")

خروجی این دستور به صورت زیر خواهد بود. مشخص است که دو متغیر جدید اضافه و متغیر quarter نیز حذف شده است.

1> separate_tidier
2   country Qrt Year growth
31        A  q1 2017   0.03
42        B  q1 2017   0.05
53        C  q1 2017   0.01
64        A  q2 2017   0.05
75        B  q2 2017   0.07
86        C  q2 2017   0.02
97        A  q3 2017   0.04
108        B  q3 2017   0.05
119        C  q3 2017   0.01
1210       A  q4 2017   0.03
1311       B  q4 2017   0.02
1412       C  q4 2017   0.04
15>

تابع $$unite()$$

توابع $$unite()$$ و $$separate()$$ عکس یکدیگر عمل می‌کنند. به این ترتیب با تابع $$unite()$$ قادر هستیم مقدارهایی دو متغیر را در یک متغیر قرار دهیم.

شکل دستوری و بعضی از پارامترهای این تابع در ادامه دیده می‌شود.

1unit(data, col, conc ,sep= "", remove = TRUE)
2arguments:
3-data: The data frame used to reshape the dataset 
4-col: Name of the new column
5-conc: Name of the columns to concatenate
6-sep: Indicates the symbol used that unites the variable, i.e:  "-", "_", "&"
7-remove: Remove the old columns. By default, sets to TRUE
پارامترعملکرد
dataچارچوب داده
colنام متغیر یا ستون جدید برای داده‌های ترکیب شده
concاسامی متغیرهایی که مقدارهایشان باید ترکیب شوند
sepعلامت جداکننده برای مقدارهای ترکیب شده
removeمقدار منطقی به منظور حذف ستون یا متغیرهای conc از مجموعه داده- پیش‌فرض TRUE

همانطور که در قسمت قبل دیدید، متغیرهای Qrt و Year را ایجاد کردیم. حال قصد داریم این مقدارهای متغیرها را ترکیب کرده و در یک متغیر جدید به نام Quarter قرار دهیم. کد زیر به این منظور تهیه شده است.

1unit_tidier=unite(separate_tidier, Quarter, Qrt, Year, sep ="_")

با اجرای این دستور، خروجی به صورت زیر ساخته می‌شود. مشخص است از آنجایی که مقدار پیش‌فرض برای پارامتر remove مقدار TRUE است، متغیرهای اولیه که برای ترکیب به کار رفته‌اند، در خروجی حذف شده‌اند.

1> unit_tidier
2   country Quarter growth
31        A q1_2017   0.03
42        B q1_2017   0.05
53        C q1_2017   0.01
64        A q2_2017   0.05
75        B q2_2017   0.07
86        C q2_2017   0.02
97        A q3_2017   0.04
108        B q3_2017   0.05
119        C q3_2017   0.01
1210       A q4_2017   0.03
1311       B q4_2017   0.02
1412       C q4_2017   0.04
15>

همانطور که دیده می‌شود، مجموعه داده اولیه که در قسمت‌های قبلی با نام tidier داشتیم بازسازی شده است.

خلاصه

در انتها خلاصه‌ای از توابع به کار رفته در این نوشتار به همراه پارامتر و کاربردهایشان دیده می‌شود. ابتدا توابع خانواده join معرفی می‌شوند.

تابعشرحپارامترهاکلیدهای چندتایی
$$left\_join()$$ادغام از چپ دو مجموعه داده- حفظ همه داده‌های x

x, y, by

دارد
$$right\_join()$$ادغام از راست دو مجموعه داده- حفظ همه داده‌های yx, y, byدارد
$$inner\_join()$$ادغام دو مجموعه داده با اعضای مشترکx, y, byدارد
$$full\_join()$$ادغام دو مجموعه داده با اعضای مشترک و غیر مشترکx, y, byدارد
$$semi\_join()$$فیلتر مجموعه داده x برحسب مشاهدات مشترک با yx, y, byدارد
$$anti\_join()$$فیلتر مجموعه داده x برحسب مشاهدات غیر مشترک با yx, y, byدارد

همچنین جدول زیر نیز به معرفی توابع معروف کتابخانه tidyr پرداخته است.

تابعشرحپارمتر
$$gather()$$تبدیل داده‌های جدول گسترده به ستون‌های کمترdata, key, value
$$spread()$$تبدیل داده‌های جدول با ستون‌های بیشترdata, key, value
$$separate()$$تفکیک مقدارهای یک متغیر به چند متغیرdata, col, into, sep, remove
$$unite()$$ادغام مقدارهای چند متغیر در یک متغیرdata, col, conc, into, sep, remove

اگر مطلب بالا برای شما مفید بوده، آموزش‌ها و مطالب زیر نیز که در زمینه به کار‌گیری آمار و محاسبات در نرم‌افزار R هستند، به شما پیشنهاد می‌شوند:

^^

بر اساس رای ۶ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *