{ "nbformat": 4, "nbformat_minor": 2, "metadata": { "colab": { "name": "lesson_2-R.ipynb", "provenance": [], "collapsed_sections": [], "toc_visible": true }, "kernelspec": { "name": "ir", "display_name": "R" }, "language_info": { "name": "R" }, "coopTranslator": { "original_hash": "f3c335f9940cfd76528b3ef918b9b342", "translation_date": "2025-09-06T13:56:29+00:00", "source_file": "2-Regression/2-Data/solution/R/lesson_2-R.ipynb", "language_code": "vi" } }, "cells": [ { "cell_type": "markdown", "source": [ "# Xây dựng mô hình hồi quy: chuẩn bị và trực quan hóa dữ liệu\n", "\n", "## **Hồi quy tuyến tính cho bí ngô - Bài học 2**\n", "#### Giới thiệu\n", "\n", "Bây giờ bạn đã có các công cụ cần thiết để bắt đầu xây dựng mô hình học máy với Tidymodels và Tidyverse, bạn đã sẵn sàng để bắt đầu đặt câu hỏi về dữ liệu của mình. Khi làm việc với dữ liệu và áp dụng các giải pháp ML, điều rất quan trọng là phải hiểu cách đặt câu hỏi đúng để khai thác tối đa tiềm năng của tập dữ liệu.\n", "\n", "Trong bài học này, bạn sẽ học:\n", "\n", "- Cách chuẩn bị dữ liệu của bạn để xây dựng mô hình.\n", "\n", "- Cách sử dụng `ggplot2` để trực quan hóa dữ liệu.\n", "\n", "Câu hỏi bạn cần trả lời sẽ quyết định loại thuật toán ML mà bạn sẽ sử dụng. Và chất lượng của câu trả lời bạn nhận được sẽ phụ thuộc rất nhiều vào bản chất của dữ liệu.\n", "\n", "Hãy cùng xem điều này qua một bài tập thực hành.\n", "\n", "\n", "

\n", " \n", "

Tác phẩm nghệ thuật của @allison_horst
\n", "\n", "\n", "\n" ], "metadata": { "id": "Pg5aexcOPqAZ" } }, { "cell_type": "markdown", "source": [ "## 1. Nhập dữ liệu về bí ngô và triệu hồi Tidyverse\n", "\n", "Chúng ta sẽ cần các gói sau để phân tích và xử lý bài học này:\n", "\n", "- `tidyverse`: [tidyverse](https://www.tidyverse.org/) là một [bộ sưu tập các gói R](https://www.tidyverse.org/packages) được thiết kế để làm cho khoa học dữ liệu trở nên nhanh hơn, dễ dàng hơn và thú vị hơn!\n", "\n", "Bạn có thể cài đặt chúng bằng cách:\n", "\n", "`install.packages(c(\"tidyverse\"))`\n", "\n", "Đoạn mã dưới đây kiểm tra xem bạn đã có các gói cần thiết để hoàn thành module này chưa và sẽ cài đặt chúng cho bạn nếu thiếu.\n" ], "metadata": { "id": "dc5WhyVdXAjR" } }, { "cell_type": "code", "execution_count": null, "source": [ "suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n", "pacman::p_load(tidyverse)" ], "outputs": [], "metadata": { "id": "GqPYUZgfXOBt" } }, { "cell_type": "markdown", "source": [ "Bây giờ, hãy khởi động một số gói và tải [dữ liệu](https://github.com/microsoft/ML-For-Beginners/blob/main/2-Regression/data/US-pumpkins.csv) được cung cấp cho bài học này!\n" ], "metadata": { "id": "kvjDTPDSXRr2" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Load the core Tidyverse packages\n", "library(tidyverse)\n", "\n", "# Import the pumpkins data\n", "pumpkins <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/2-Regression/data/US-pumpkins.csv\")\n", "\n", "\n", "# Get a glimpse and dimensions of the data\n", "glimpse(pumpkins)\n", "\n", "\n", "# Print the first 50 rows of the data set\n", "pumpkins %>% \n", " slice_head(n =50)" ], "outputs": [], "metadata": { "id": "VMri-t2zXqgD" } }, { "cell_type": "markdown", "source": [ "Một `glimpse()` nhanh chóng cho thấy rằng có các giá trị trống và sự kết hợp giữa chuỗi ký tự (`chr`) và dữ liệu số (`dbl`). Cột `Date` thuộc kiểu ký tự và còn có một cột kỳ lạ tên là `Package`, nơi dữ liệu là sự pha trộn giữa `sacks`, `bins` và các giá trị khác. Thực tế, dữ liệu này khá lộn xộn 😤.\n", "\n", "Thực tế, không thường xuyên bạn nhận được một tập dữ liệu hoàn toàn sẵn sàng để sử dụng nhằm tạo ra một mô hình ML ngay lập tức. Nhưng đừng lo, trong bài học này, bạn sẽ học cách chuẩn bị một tập dữ liệu thô bằng cách sử dụng các thư viện R tiêu chuẩn 🧑‍🔧. Bạn cũng sẽ học các kỹ thuật khác nhau để trực quan hóa dữ liệu. 📈📊\n", "
\n", "\n", "> Một lời nhắc lại: Toán tử pipe (`%>%`) thực hiện các thao tác theo trình tự logic bằng cách chuyển một đối tượng vào một hàm hoặc biểu thức gọi. Bạn có thể nghĩ toán tử pipe như đang nói \"và sau đó\" trong mã của bạn.\n" ], "metadata": { "id": "REWcIv9yX29v" } }, { "cell_type": "markdown", "source": [ "## 2. Kiểm tra dữ liệu bị thiếu\n", "\n", "Một trong những vấn đề phổ biến nhất mà các nhà khoa học dữ liệu phải đối mặt là dữ liệu không đầy đủ hoặc bị thiếu. R biểu thị các giá trị bị thiếu hoặc không xác định bằng một giá trị đặc biệt: `NA` (Not Available).\n", "\n", "Vậy làm thế nào để chúng ta biết rằng khung dữ liệu chứa các giá trị bị thiếu?\n", "
\n", "- Một cách đơn giản là sử dụng hàm cơ bản của R `anyNA`, hàm này trả về các đối tượng logic `TRUE` hoặc `FALSE`.\n" ], "metadata": { "id": "Zxfb3AM5YbUe" } }, { "cell_type": "code", "execution_count": null, "source": [ "pumpkins %>% \n", " anyNA()" ], "outputs": [], "metadata": { "id": "G--DQutAYltj" } }, { "cell_type": "markdown", "source": [ "Tuyệt vời, có vẻ như đang thiếu một số dữ liệu! Đây là một điểm tốt để bắt đầu.\n", "\n", "- Một cách khác là sử dụng hàm `is.na()` để xác định các phần tử bị thiếu trong từng cột với giá trị logic `TRUE`.\n" ], "metadata": { "id": "mU-7-SB6YokF" } }, { "cell_type": "code", "execution_count": null, "source": [ "pumpkins %>% \n", " is.na() %>% \n", " head(n = 7)" ], "outputs": [], "metadata": { "id": "W-DxDOR4YxSW" } }, { "cell_type": "markdown", "source": [ "Được rồi, đã hoàn thành công việc nhưng với một khung dữ liệu lớn như thế này, việc xem xét từng hàng và cột riêng lẻ sẽ không hiệu quả và gần như không thể😴.\n", "\n", "- Một cách trực quan hơn là tính tổng số giá trị bị thiếu cho mỗi cột:\n" ], "metadata": { "id": "xUWxipKYY0o7" } }, { "cell_type": "code", "execution_count": null, "source": [ "pumpkins %>% \n", " is.na() %>% \n", " colSums()" ], "outputs": [], "metadata": { "id": "ZRBWV6P9ZArL" } }, { "cell_type": "markdown", "source": [ "Tốt hơn nhiều! Có dữ liệu bị thiếu, nhưng có lẽ điều đó sẽ không ảnh hưởng đến nhiệm vụ hiện tại. Hãy xem phân tích tiếp theo sẽ mang lại điều gì.\n", "\n", "> Bên cạnh các bộ gói và hàm tuyệt vời, R còn có tài liệu hướng dẫn rất tốt. Ví dụ, sử dụng `help(colSums)` hoặc `?colSums` để tìm hiểu thêm về hàm này.\n" ], "metadata": { "id": "9gv-crB6ZD1Y" } }, { "cell_type": "markdown", "source": [ "## 3. Dplyr: Ngữ pháp của việc xử lý dữ liệu\n", "\n", "

\n", " \n", "

Tác phẩm nghệ thuật của @allison_horst
\n", "\n", "\n", "\n" ], "metadata": { "id": "o4jLY5-VZO2C" } }, { "cell_type": "markdown", "source": [ "[`dplyr`](https://dplyr.tidyverse.org/), một gói trong Tidyverse, là một ngữ pháp xử lý dữ liệu cung cấp một tập hợp các động từ nhất quán giúp bạn giải quyết các thách thức xử lý dữ liệu phổ biến nhất. Trong phần này, chúng ta sẽ khám phá một số động từ của dplyr! \n", "
\n" ], "metadata": { "id": "i5o33MQBZWWw" } }, { "cell_type": "markdown", "source": [ "#### dplyr::select()\n", "\n", "`select()` là một hàm trong gói `dplyr` giúp bạn chọn các cột để giữ lại hoặc loại bỏ.\n", "\n", "Để làm cho khung dữ liệu của bạn dễ làm việc hơn, hãy loại bỏ một số cột bằng cách sử dụng `select()`, chỉ giữ lại các cột bạn cần.\n", "\n", "Ví dụ, trong bài tập này, phân tích của chúng ta sẽ liên quan đến các cột `Package`, `Low Price`, `High Price` và `Date`. Hãy chọn các cột này.\n" ], "metadata": { "id": "x3VGMAGBZiUr" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Select desired columns\n", "pumpkins <- pumpkins %>% \n", " select(Package, `Low Price`, `High Price`, Date)\n", "\n", "\n", "# Print data set\n", "pumpkins %>% \n", " slice_head(n = 5)" ], "outputs": [], "metadata": { "id": "F_FgxQnVZnM0" } }, { "cell_type": "markdown", "source": [ "#### dplyr::mutate()\n", "\n", "`mutate()` là một hàm trong gói `dplyr`, giúp bạn tạo hoặc chỉnh sửa các cột, đồng thời giữ nguyên các cột hiện có.\n", "\n", "Cấu trúc chung của `mutate` là:\n", "\n", "`data %>% mutate(new_column_name = what_it_contains)`\n", "\n", "Hãy thử sử dụng `mutate` với cột `Date` bằng cách thực hiện các thao tác sau:\n", "\n", "1. Chuyển đổi các ngày (hiện tại thuộc kiểu ký tự) sang định dạng tháng (đây là ngày tháng kiểu Mỹ, nên định dạng là `MM/DD/YYYY`).\n", "\n", "2. Trích xuất tháng từ các ngày và lưu vào một cột mới.\n", "\n", "Trong R, gói [lubridate](https://lubridate.tidyverse.org/) giúp làm việc với dữ liệu ngày giờ dễ dàng hơn. Vì vậy, hãy sử dụng `dplyr::mutate()`, `lubridate::mdy()`, `lubridate::month()` để đạt được các mục tiêu trên. Chúng ta có thể loại bỏ cột `Date` vì sẽ không cần sử dụng nó nữa trong các thao tác tiếp theo.\n" ], "metadata": { "id": "2KKo0Ed9Z1VB" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Load lubridate\n", "library(lubridate)\n", "\n", "pumpkins <- pumpkins %>% \n", " # Convert the Date column to a date object\n", " mutate(Date = mdy(Date)) %>% \n", " # Extract month from Date\n", " mutate(Month = month(Date)) %>% \n", " # Drop Date column\n", " select(-Date)\n", "\n", "# View the first few rows\n", "pumpkins %>% \n", " slice_head(n = 7)" ], "outputs": [], "metadata": { "id": "5joszIVSZ6xe" } }, { "cell_type": "markdown", "source": [ "Woohoo! 🤩\n", "\n", "Tiếp theo, hãy tạo một cột mới `Price`, đại diện cho giá trung bình của một quả bí ngô. Bây giờ, hãy lấy trung bình của các cột `Low Price` và `High Price` để điền vào cột Price mới. \n", "
\n" ], "metadata": { "id": "nIgLjNMCZ-6Y" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Create a new column Price\n", "pumpkins <- pumpkins %>% \n", " mutate(Price = (`Low Price` + `High Price`)/2)\n", "\n", "# View the first few rows of the data\n", "pumpkins %>% \n", " slice_head(n = 5)" ], "outputs": [], "metadata": { "id": "Zo0BsqqtaJw2" } }, { "cell_type": "markdown", "source": [ "Yeees!💪\n", "\n", "\"Nhưng khoan đã!\", bạn sẽ nói sau khi lướt qua toàn bộ tập dữ liệu với `View(pumpkins)`, \"Có điều gì đó kỳ lạ ở đây!\"🤔\n", "\n", "Nếu bạn nhìn vào cột `Package`, bí ngô được bán theo nhiều cách khác nhau. Một số được bán theo đơn vị `1 1/9 bushel`, một số theo đơn vị `1/2 bushel`, một số theo từng quả bí ngô, một số theo cân nặng, và một số được đóng trong các hộp lớn với kích thước khác nhau.\n", "\n", "Hãy kiểm tra điều này:\n" ], "metadata": { "id": "p77WZr-9aQAR" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Verify the distinct observations in Package column\n", "pumpkins %>% \n", " distinct(Package)" ], "outputs": [], "metadata": { "id": "XISGfh0IaUy6" } }, { "cell_type": "markdown", "source": [ "Tuyệt vời!👏\n", "\n", "Bí ngô dường như rất khó để cân một cách nhất quán, vì vậy hãy lọc chúng bằng cách chỉ chọn những quả bí ngô có chuỗi *bushel* trong cột `Package` và đặt chúng vào một khung dữ liệu mới `new_pumpkins`.\n" ], "metadata": { "id": "7sMjiVujaZxY" } }, { "cell_type": "markdown", "source": [ "#### dplyr::filter() và stringr::str_detect()\n", "\n", "[`dplyr::filter()`](https://dplyr.tidyverse.org/reference/filter.html): tạo một tập con của dữ liệu chỉ chứa **các hàng** thỏa mãn điều kiện của bạn, trong trường hợp này là các hàng có từ *bushel* trong cột `Package`.\n", "\n", "[stringr::str_detect()](https://stringr.tidyverse.org/reference/str_detect.html): phát hiện sự có mặt hoặc vắng mặt của một mẫu trong chuỗi.\n", "\n", "Gói [`stringr`](https://github.com/tidyverse/stringr) cung cấp các hàm đơn giản cho các thao tác chuỗi thông dụng.\n" ], "metadata": { "id": "L8Qfcs92ageF" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Retain only pumpkins with \"bushel\"\n", "new_pumpkins <- pumpkins %>% \n", " filter(str_detect(Package, \"bushel\"))\n", "\n", "# Get the dimensions of the new data\n", "dim(new_pumpkins)\n", "\n", "# View a few rows of the new data\n", "new_pumpkins %>% \n", " slice_head(n = 5)" ], "outputs": [], "metadata": { "id": "hy_SGYREampd" } }, { "cell_type": "markdown", "source": [ "Bạn có thể thấy rằng chúng tôi đã thu hẹp xuống còn khoảng 415 dòng dữ liệu chứa bí ngô theo giạ.🤩\n", "
\n" ], "metadata": { "id": "VrDwF031avlR" } }, { "cell_type": "markdown", "source": [ "#### dplyr::case_when()\n", "\n", "**Nhưng khoan đã! Còn một việc nữa cần làm**\n", "\n", "Bạn có nhận thấy rằng số lượng giạ thay đổi theo từng hàng không? Bạn cần chuẩn hóa giá để hiển thị giá theo mỗi giạ, không phải theo 1 1/9 hay 1/2 giạ. Đã đến lúc thực hiện một số phép toán để chuẩn hóa.\n", "\n", "Chúng ta sẽ sử dụng hàm [`case_when()`](https://dplyr.tidyverse.org/reference/case_when.html) để *biến đổi* cột Price dựa trên một số điều kiện. `case_when` cho phép bạn vector hóa nhiều câu lệnh `if_else()`.\n" ], "metadata": { "id": "mLpw2jH4a0tx" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Convert the price if the Package contains fractional bushel values\n", "new_pumpkins <- new_pumpkins %>% \n", " mutate(Price = case_when(\n", " str_detect(Package, \"1 1/9\") ~ Price/(1 + 1/9),\n", " str_detect(Package, \"1/2\") ~ Price/(1/2),\n", " TRUE ~ Price))\n", "\n", "# View the first few rows of the data\n", "new_pumpkins %>% \n", " slice_head(n = 30)" ], "outputs": [], "metadata": { "id": "P68kLVQmbM6I" } }, { "cell_type": "markdown", "source": [ "Bây giờ, chúng ta có thể phân tích giá theo đơn vị dựa trên đo lường bằng giạ. Tuy nhiên, tất cả việc nghiên cứu về giạ bí ngô này cho thấy rằng việc `hiểu rõ bản chất của dữ liệu` của bạn là điều `rất quan trọng`!\n", "\n", "> ✅ Theo [The Spruce Eats](https://www.thespruceeats.com/how-much-is-a-bushel-1389308), trọng lượng của một giạ phụ thuộc vào loại nông sản, vì đây là một đơn vị đo thể tích. \"Ví dụ, một giạ cà chua được cho là nặng 56 pound... Lá và rau xanh chiếm nhiều không gian hơn nhưng lại nhẹ hơn, vì vậy một giạ rau chân vịt chỉ nặng 20 pound.\" Thật là phức tạp! Chúng ta không cần phải bận tâm đến việc chuyển đổi từ giạ sang pound, thay vào đó hãy định giá theo giạ. Tuy nhiên, tất cả việc nghiên cứu về giạ bí ngô này cho thấy rằng việc hiểu rõ bản chất của dữ liệu của bạn là điều rất quan trọng!\n", ">\n", "> ✅ Bạn có để ý rằng bí ngô được bán theo nửa giạ có giá rất đắt không? Bạn có thể tìm ra lý do tại sao không? Gợi ý: những quả bí ngô nhỏ đắt hơn rất nhiều so với những quả lớn, có lẽ vì có nhiều quả nhỏ hơn trong một giạ, do không gian bị chiếm bởi một quả bí ngô lớn rỗng ruột.\n" ], "metadata": { "id": "pS2GNPagbSdb" } }, { "cell_type": "markdown", "source": [ "Bây giờ cuối cùng, chỉ để thêm phần thú vị 💁‍♀️, hãy di chuyển cột Month lên vị trí đầu tiên, tức là `trước` cột `Package`.\n", "\n", "`dplyr::relocate()` được sử dụng để thay đổi vị trí các cột.\n" ], "metadata": { "id": "qql1SowfbdnP" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Create a new data frame new_pumpkins\n", "new_pumpkins <- new_pumpkins %>% \n", " relocate(Month, .before = Package)\n", "\n", "new_pumpkins %>% \n", " slice_head(n = 7)" ], "outputs": [], "metadata": { "id": "JJ1x6kw8bixF" } }, { "cell_type": "markdown", "source": [ "Làm tốt lắm!👌 Giờ bạn đã có một tập dữ liệu sạch sẽ, gọn gàng để xây dựng mô hình hồi quy mới của mình! \n", "
\n" ], "metadata": { "id": "y8TJ0Za_bn5Y" } }, { "cell_type": "markdown", "source": [ "## 4. Trực quan hóa dữ liệu với ggplot2\n", "\n", "

\n", " \n", "

Đồ họa thông tin bởi Dasani Madipalli
\n", "\n", "\n", "\n", "\n", "Có một câu nói *thông thái* như sau:\n", "\n", "> \"Biểu đồ đơn giản đã mang lại nhiều thông tin hơn cho nhà phân tích dữ liệu so với bất kỳ công cụ nào khác.\" --- John Tukey\n", "\n", "Một phần vai trò của nhà khoa học dữ liệu là thể hiện chất lượng và bản chất của dữ liệu mà họ đang làm việc. Để làm điều này, họ thường tạo ra các hình ảnh trực quan thú vị, hoặc các biểu đồ, đồ thị, và sơ đồ, thể hiện các khía cạnh khác nhau của dữ liệu. Bằng cách này, họ có thể trực quan hóa các mối quan hệ và khoảng trống mà nếu không sẽ khó phát hiện.\n", "\n", "Các hình ảnh trực quan cũng có thể giúp xác định kỹ thuật học máy phù hợp nhất với dữ liệu. Ví dụ, một biểu đồ phân tán có xu hướng theo một đường thẳng cho thấy dữ liệu là ứng viên tốt cho bài toán hồi quy tuyến tính.\n", "\n", "R cung cấp một số hệ thống để tạo biểu đồ, nhưng [`ggplot2`](https://ggplot2.tidyverse.org/index.html) là một trong những hệ thống thanh lịch và linh hoạt nhất. `ggplot2` cho phép bạn tạo biểu đồ bằng cách **kết hợp các thành phần độc lập**.\n", "\n", "Hãy bắt đầu với một biểu đồ phân tán đơn giản cho các cột Price và Month.\n", "\n", "Trong trường hợp này, chúng ta sẽ bắt đầu với [`ggplot()`](https://ggplot2.tidyverse.org/reference/ggplot.html), cung cấp một tập dữ liệu và ánh xạ thẩm mỹ (với [`aes()`](https://ggplot2.tidyverse.org/reference/aes.html)) sau đó thêm các lớp (như [`geom_point()`](https://ggplot2.tidyverse.org/reference/geom_point.html)) cho biểu đồ phân tán.\n" ], "metadata": { "id": "mYSH6-EtbvNa" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Set a theme for the plots\n", "theme_set(theme_light())\n", "\n", "# Create a scatter plot\n", "p <- ggplot(data = new_pumpkins, aes(x = Price, y = Month))\n", "p + geom_point()" ], "outputs": [], "metadata": { "id": "g2YjnGeOcLo4" } }, { "cell_type": "markdown", "source": [ "Đây có phải là một biểu đồ hữu ích không 🤷? Có điều gì khiến bạn ngạc nhiên về nó không?\n", "\n", "Nó không thực sự hữu ích vì tất cả những gì nó làm chỉ là hiển thị dữ liệu của bạn dưới dạng một loạt các điểm trong một tháng nhất định. \n", "
\n" ], "metadata": { "id": "Ml7SDCLQcPvE" } }, { "cell_type": "markdown", "source": [ "### **Làm thế nào để chúng ta làm cho nó hữu ích?**\n", "\n", "Để biểu đồ hiển thị dữ liệu hữu ích, bạn thường cần nhóm dữ liệu theo một cách nào đó. Ví dụ, trong trường hợp của chúng ta, tìm giá trung bình của bí ngô theo từng tháng sẽ cung cấp thêm thông tin chi tiết về các mẫu ẩn trong dữ liệu. Điều này dẫn chúng ta đến một công cụ khác của **dplyr**:\n", "\n", "#### `dplyr::group_by() %>% summarize()`\n", "\n", "Việc tính toán tổng hợp theo nhóm trong R có thể được thực hiện dễ dàng bằng cách sử dụng\n", "\n", "`dplyr::group_by() %>% summarize()`\n", "\n", "- `dplyr::group_by()` thay đổi đơn vị phân tích từ toàn bộ tập dữ liệu sang các nhóm riêng lẻ, chẳng hạn như theo từng tháng.\n", "\n", "- `dplyr::summarize()` tạo một khung dữ liệu mới với một cột cho mỗi biến nhóm và một cột cho mỗi thống kê tóm tắt mà bạn đã chỉ định.\n", "\n", "Ví dụ, chúng ta có thể sử dụng `dplyr::group_by() %>% summarize()` để nhóm các bí ngô thành các nhóm dựa trên cột **Month** và sau đó tìm **giá trung bình** cho từng tháng.\n" ], "metadata": { "id": "jMakvJZIcVkh" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Find the average price of pumpkins per month\r\n", "new_pumpkins %>%\r\n", " group_by(Month) %>% \r\n", " summarise(mean_price = mean(Price))" ], "outputs": [], "metadata": { "id": "6kVSUa2Bcilf" } }, { "cell_type": "markdown", "source": [ "Ngắn gọn!✨\n", "\n", "Các đặc điểm phân loại như tháng được biểu diễn tốt hơn bằng biểu đồ cột 📊. Các lớp chịu trách nhiệm cho biểu đồ cột là `geom_bar()` và `geom_col()`. Tham khảo `?geom_bar` để tìm hiểu thêm.\n", "\n", "Hãy cùng tạo một cái nhé!\n" ], "metadata": { "id": "Kds48GUBcj3W" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Find the average price of pumpkins per month then plot a bar chart\r\n", "new_pumpkins %>%\r\n", " group_by(Month) %>% \r\n", " summarise(mean_price = mean(Price)) %>% \r\n", " ggplot(aes(x = Month, y = mean_price)) +\r\n", " geom_col(fill = \"midnightblue\", alpha = 0.7) +\r\n", " ylab(\"Pumpkin Price\")" ], "outputs": [], "metadata": { "id": "VNbU1S3BcrxO" } }, { "cell_type": "markdown", "source": [ "🤩🤩 Đây là một biểu đồ trực quan hóa dữ liệu hữu ích hơn! Dường như nó chỉ ra rằng giá cao nhất của bí ngô xảy ra vào tháng 9 và tháng 10. Điều này có đúng với mong đợi của bạn không? Tại sao hoặc tại sao không?\n", "\n", "Chúc mừng bạn đã hoàn thành bài học thứ hai 👏! Bạn đã chuẩn bị dữ liệu của mình để xây dựng mô hình, sau đó khám phá thêm nhiều thông tin chi tiết bằng cách sử dụng biểu đồ trực quan hóa!\n" ], "metadata": { "id": "zDm0VOzzcuzR" } }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n---\n\n**Tuyên bố miễn trừ trách nhiệm**: \nTài liệu này đã được dịch bằng dịch vụ dịch thuật AI [Co-op Translator](https://github.com/Azure/co-op-translator). Mặc dù chúng tôi cố gắng đảm bảo độ chính xác, xin lưu ý rằng các bản dịch tự động có thể chứa lỗi hoặc không chính xác. Tài liệu gốc bằng ngôn ngữ bản địa nên được coi là nguồn thông tin chính thức. Đối với các thông tin quan trọng, khuyến nghị sử dụng dịch vụ dịch thuật chuyên nghiệp bởi con người. Chúng tôi không chịu trách nhiệm cho bất kỳ sự hiểu lầm hoặc diễn giải sai nào phát sinh từ việc sử dụng bản dịch này.\n" ] } ] }