Hướng dẫn vẽ biểu đồ cột trong R

Biên soạn: Duc Nguyen | Chuyên đào tạo kỹ năng xử lý dữ liệu sử dụng phần mềm R | Website: www.tuhocr.com

Tình huống

Bạn có 1 file Excel ghi lại kết quả phân tích mẫu đất ở 9 địa điểm như sau. ket_qua_phan_tich_dat_full.xlsx

Yêu cầu xuất ra báo cáo ở dạng đồ thị cột, tính meansd cho từng chỉ tiêu.

Cách thực hiện

Xử lý dữ liệu đầu vào (clean dataset)

Các bạn download file Excel về để trong thư mục project (working directory) rồi áp dụng code mẫu như sau.

# Đọc file Excel ở range chứa dữ liệu tương ứng
library(readxl)
ket_qua <- read_excel("D:/tuhocr/ket_qua_phan_tich_dat_full.xlsx", range = "B6:O15")

# Kiểm tra dataset
str(ket_qua)
## tibble [9 × 14] (S3: tbl_df/tbl/data.frame)
##  $ TT        : num [1:9] 1 2 3 4 5 6 7 8 9
##  $ location  : chr [1:9] "BÌNH MINH" "CHÂU THÀNH" "THƯỜNG XUÂN" "AN ĐỊNH" ...
##  $ pH-1      : num [1:9] 5.33 6.5 5.99 7.3 6.62 7.2 5.33 6.2 7.11
##  $ pH-2      : num [1:9] 5.92 7.2 5.4 7.12 6.25 7.1 5.9 6.21 7.36
##  $ pH-3      : num [1:9] 6.1 6.8 5.7 6.8 6.3 6.8 5.54 6.5 6.78
##  $ salinity-1: num [1:9] 3.2 0.25 2.1 1.21 0.23 0.24 2.3 3.6 1.33
##  $ salinity-2: num [1:9] 2.8 0 1.58 0.87 0.36 0.18 1.79 3.6 1.4
##  $ salinity-3: num [1:9] 2.9 0.01 2 0.6 0.23 0.14 2.1 3.87 1.54
##  $ organic-1 : num [1:9] 14 21 8 14 22 14 17.2 4.33 9.12
##  $ organic-2 : num [1:9] 12 22 9.3 15.5 19 15.3 17.9 4.5 10
##  $ organic-3 : num [1:9] 15.2 21.2 12 13 21.2 14.2 16.3 4.19 10.2
##  $ nitrogen-1: num [1:9] 2 1.25 0.36 1.2 0.33 1.23 2.2 1.7 0.99
##  $ nitrogen-2: num [1:9] 2.1 1.8 0.5 1.33 0.5 1.21 2.1 1.72 0.78
##  $ nitrogen-3: num [1:9] 3 0.9 0.6 1 0.42 1.5 2.36 1.79 1.1
# Kiểm tra tên cột
names(ket_qua)
##  [1] "TT"         "location"   "pH-1"       "pH-2"       "pH-3"      
##  [6] "salinity-1" "salinity-2" "salinity-3" "organic-1"  "organic-2" 
## [11] "organic-3"  "nitrogen-1" "nitrogen-2" "nitrogen-3"
# Tính `mean` và `sd` ở từng chỉ tiêu tương ứng
library(tidyverse)

ket_qua_clean <- ket_qua %>% group_by(location) %>% # tính theo địa điểm
    
    # tính mean và sd cho pH
    mutate(pH_mean = mean(c(`pH-1`,`pH-2`,`pH-3`))) %>% 
    mutate(pH_sd = sd(c(`pH-1`,`pH-2`,`pH-3`))) %>%
    
    # tính mean và sd cho salinity
    mutate(salinity_mean = mean(c(`salinity-1`,`salinity-2`,`salinity-3`))) %>%
    mutate(salinity_sd = sd(c(`salinity-1`,`salinity-2`,`salinity-3`))) %>%
    
    # tính mean và sd cho organic matter
    mutate(organic_mean = mean(c(`organic-1`,`organic-2`,`organic-3`))) %>%
    mutate(organic_sd = sd(c(`organic-1`,`organic-2`,`organic-3`))) %>%
    
    # tính mean và sd cho nitrogen
    mutate(nitrogen_mean = mean(c(`nitrogen-1`,`nitrogen-2`,`nitrogen-3`))) %>%
    mutate(nitrogen_sd = sd(c(`nitrogen-1`,`nitrogen-2`,`nitrogen-3`))) %>%
    
    # chọn ra các cột đưa vào dataset clean
    select(location,
           pH_mean, pH_sd,
           salinity_mean, salinity_sd,
           organic_mean, organic_sd,
           nitrogen_mean, nitrogen_sd)

# Dataset sau xử lý
ket_qua_clean <- as.data.frame(ket_qua_clean)
ket_qua_clean 
##      location  pH_mean     pH_sd salinity_mean salinity_sd organic_mean
## 1   BÌNH MINH 5.783333 0.4027820    2.96666667  0.20816660    13.733333
## 2  CHÂU THÀNH 6.833333 0.3511885    0.08666667  0.14153916    21.400000
## 3 THƯỜNG XUÂN 5.696667 0.2950141    1.89333333  0.27592269     9.766667
## 4     AN ĐỊNH 7.073333 0.2532456    0.89333333  0.30566867    14.166667
## 5     AN BÌNH 6.390000 0.2007486    0.27333333  0.07505553    20.733333
## 6  GIANG ĐIỀN 7.033333 0.2081666    0.18666667  0.05033223    14.500000
## 7   XUÂN THỚI 5.590000 0.2882707    2.06333333  0.25696952    17.133333
## 8    LONG HÒA 6.303333 0.1703917    3.69000000  0.15588457     4.340000
## 9   LONG ĐỊNH 7.083333 0.2909181    1.42333333  0.10692677     9.773333
##   organic_sd nitrogen_mean nitrogen_sd
## 1  1.6165808     2.3666667  0.55075705
## 2  0.5291503     1.3166667  0.45368859
## 3  2.0404248     0.4866667  0.12055428
## 4  1.2583057     1.1766667  0.16623277
## 5  1.5534907     0.4166667  0.08504901
## 6  0.7000000     1.3133333  0.16196707
## 7  0.8020806     2.2200000  0.13114877
## 8  0.1552417     1.7366667  0.04725816
## 9  0.5745723     0.9566667  0.16258331

Tách dữ liệu phục vụ vẽ đồ thị

Ý tưởng là từ dataset ket_qua_clean đã thu được gồm các cột đã tính meansd tương ứng cho từng chỉ tiêu. Ta cần tách ra thành các bộ dữ liệu nhỏ để vẽ riêng từng đồ thị.

Chỉ tiêu pH

# PH MEAN
ph_mean_data <- ket_qua_clean %>% select(location, pH_mean) 
rownames(ph_mean_data) <- ph_mean_data[, 1]
ph_mean_data <- as.matrix(ph_mean_data[, -1, drop = FALSE])
ph_mean_data 
##              pH_mean
## BÌNH MINH   5.783333
## CHÂU THÀNH  6.833333
## THƯỜNG XUÂN 5.696667
## AN ĐỊNH     7.073333
## AN BÌNH     6.390000
## GIANG ĐIỀN  7.033333
## XUÂN THỚI   5.590000
## LONG HÒA    6.303333
## LONG ĐỊNH   7.083333
# PH SD
ph_sd_data <- ket_qua_clean %>% select(location, pH_sd) 
rownames(ph_sd_data) <- ph_sd_data[, 1]
ph_sd_data <- as.matrix(ph_sd_data[, -1, drop = FALSE])
ph_sd_data
##                 pH_sd
## BÌNH MINH   0.4027820
## CHÂU THÀNH  0.3511885
## THƯỜNG XUÂN 0.2950141
## AN ĐỊNH     0.2532456
## AN BÌNH     0.2007486
## GIANG ĐIỀN  0.2081666
## XUÂN THỚI   0.2882707
## LONG HÒA    0.1703917
## LONG ĐỊNH   0.2909181

Chỉ tiêu độ mặn (‰)

# SALINITY MEAN
salinity_mean_data <- ket_qua_clean %>% select(location, salinity_mean) 
rownames(salinity_mean_data) <- salinity_mean_data[, 1]
salinity_mean_data <- as.matrix(salinity_mean_data[, -1, drop = FALSE])
salinity_mean_data 
##             salinity_mean
## BÌNH MINH      2.96666667
## CHÂU THÀNH     0.08666667
## THƯỜNG XUÂN    1.89333333
## AN ĐỊNH        0.89333333
## AN BÌNH        0.27333333
## GIANG ĐIỀN     0.18666667
## XUÂN THỚI      2.06333333
## LONG HÒA       3.69000000
## LONG ĐỊNH      1.42333333
# SALINITY SD
salinity_sd_data <- ket_qua_clean %>% select(location, salinity_sd) 
rownames(salinity_sd_data) <- salinity_sd_data[, 1]
salinity_sd_data <- as.matrix(salinity_sd_data[, -1, drop = FALSE])
salinity_sd_data
##             salinity_sd
## BÌNH MINH    0.20816660
## CHÂU THÀNH   0.14153916
## THƯỜNG XUÂN  0.27592269
## AN ĐỊNH      0.30566867
## AN BÌNH      0.07505553
## GIANG ĐIỀN   0.05033223
## XUÂN THỚI    0.25696952
## LONG HÒA     0.15588457
## LONG ĐỊNH    0.10692677

Chỉ tiêu hữu cơ (%)

# ORGANIC MEAN
organic_mean_data <- ket_qua_clean %>% select(location, organic_mean) 
rownames(organic_mean_data) <- organic_mean_data[, 1]
organic_mean_data <- as.matrix(organic_mean_data[, -1, drop = FALSE])
organic_mean_data
##             organic_mean
## BÌNH MINH      13.733333
## CHÂU THÀNH     21.400000
## THƯỜNG XUÂN     9.766667
## AN ĐỊNH        14.166667
## AN BÌNH        20.733333
## GIANG ĐIỀN     14.500000
## XUÂN THỚI      17.133333
## LONG HÒA        4.340000
## LONG ĐỊNH       9.773333
# ORGANIC SD
organic_sd_data <- ket_qua_clean %>% select(location, organic_sd) 
rownames(organic_sd_data) <- organic_sd_data[, 1]
organic_sd_data <- as.matrix(organic_sd_data[, -1, drop = FALSE])
organic_sd_data
##             organic_sd
## BÌNH MINH    1.6165808
## CHÂU THÀNH   0.5291503
## THƯỜNG XUÂN  2.0404248
## AN ĐỊNH      1.2583057
## AN BÌNH      1.5534907
## GIANG ĐIỀN   0.7000000
## XUÂN THỚI    0.8020806
## LONG HÒA     0.1552417
## LONG ĐỊNH    0.5745723

Chỉ tiêu nitrogen (%)

# NITROGEN MEAN
nitrogen_mean_data <- ket_qua_clean %>% select(location, nitrogen_mean) 
rownames(nitrogen_mean_data) <- nitrogen_mean_data[, 1]
nitrogen_mean_data <- as.matrix(nitrogen_mean_data[, -1, drop = FALSE])
nitrogen_mean_data
##             nitrogen_mean
## BÌNH MINH       2.3666667
## CHÂU THÀNH      1.3166667
## THƯỜNG XUÂN     0.4866667
## AN ĐỊNH         1.1766667
## AN BÌNH         0.4166667
## GIANG ĐIỀN      1.3133333
## XUÂN THỚI       2.2200000
## LONG HÒA        1.7366667
## LONG ĐỊNH       0.9566667
# NITROGEN SD
nitrogen_sd_data <- ket_qua_clean %>% select(location, nitrogen_sd) 
rownames(nitrogen_sd_data) <- nitrogen_sd_data[, 1]
nitrogen_sd_data <- as.matrix(nitrogen_sd_data[, -1, drop = FALSE])
nitrogen_sd_data
##             nitrogen_sd
## BÌNH MINH    0.55075705
## CHÂU THÀNH   0.45368859
## THƯỜNG XUÂN  0.12055428
## AN ĐỊNH      0.16623277
## AN BÌNH      0.08504901
## GIANG ĐIỀN   0.16196707
## XUÂN THỚI    0.13114877
## LONG HÒA     0.04725816
## LONG ĐỊNH    0.16258331

Vẽ đồ thị

Thiết kế hàm để vẽ error bar

Tham khảo: https://r-graph-gallery.com/4-barplot-with-error-bar.html

error.bar <- function(x, y, upper, lower = upper, length = 0.035, ...) {
    arrows(x , y + upper, x, y - lower, angle = 90, code = 3, length = length, ...)
}

# length là độ dài của error bar
# code 1, 2, 3 là các style khác nhau của error bar

Vẽ nhiều đồ thị trên cùng 1 hình

old.par <- par(mfrow = c(2, 2),
               # chỉnh khoảng cách inside từng đồ thị [bottom, left, top, right]
               mar = c(1, 4, 3, 2), 
               # chỉnh khoảng cách multiple plot
               oma = c(2, 2, 0, 7),
               xpd = NA)

### VẼ ĐỒ THỊ CHO PH
ph_barplot <- barplot(ph_mean_data, 
                      beside = TRUE,
                      # chọn dãy màu cho cột
                      col = hsv(seq(0,1 - 1/12, length.out = 12), 0.5 , 1), 
                      ylim = c(0, 10), space = 0.5, ylab = "pH", 
                      axisnames = FALSE)

error.bar(ph_barplot, ph_mean_data, ph_sd_data) # đưa error bar vào

### VẼ ĐỒ THỊ CHO SALINITY
salinity_barplot <- barplot(salinity_mean_data, 
                            beside = TRUE,
                            col = hsv(seq(0,1 - 1/12, length.out = 12), 0.5 , 1),
                            ylim = c(0, 5), space = 0.5, ylab = "Độ mặn (‰)", 
                            axisnames = FALSE)

error.bar(salinity_barplot, salinity_mean_data, salinity_sd_data)

### VẼ ĐỒ THỊ CHO ORGANIC
organic_barplot <- barplot(organic_mean_data, 
                           beside = TRUE,
                           col = hsv(seq(0,1 - 1/12, length.out = 12), 0.5 , 1),
                           ylim = c(0, 30), space = 0.5, ylab = "Hữu cơ (%)", 
                           axisnames = FALSE)

error.bar(organic_barplot, organic_mean_data, organic_sd_data)

### VẼ ĐỒ THỊ CHO NITROGEN
nitrogen_barplot <- barplot(nitrogen_mean_data, 
                            beside = TRUE,
                            col = hsv(seq(0,1 - 1/12, length.out = 12), 0.5 , 1),
                            ylim = c(0, 4), space = 0.5, ylab = "Nitrogen (%)", 
                            axisnames = FALSE)

error.bar(nitrogen_barplot, nitrogen_mean_data, nitrogen_sd_data)

### BẢNG CHÚ THÍCH
legend(15, 5, # trục x, trục y
       y.intersp = 1.5, # vertical spacing
       legend = ket_qua_clean$location,
       title = "Địa điểm lấy mẫu",
       horiz = FALSE,
       # dãy màu tương ứng từng cột
       fill = hsv(seq(0,1 - 1/12, length.out = 12), 0.5 , 1),
       box.lty = 1,
       cex = 0.8)

### TIÊU ĐỀ ĐỒ THỊ
mtext("Kết quả phân tích đất tháng 9/2022 | tuhocr.com",
      side = 3,
      line = -2,
      outer = TRUE)

### Close par
par(old.par)

### Right-click để xem hình độ phân giải cao

Sơ kết

Trên đây là ví dụ minh họa ứng dụng R để vẽ đồ thị. Bạn có thể tham gia khóa học “HDSD R để xử lý dữ liệu | Chuyên đề Coding in R”, sau 20 giờ học, bạn sẽ có nền tảng vững chắc về R căn bản để xử lý dữ liệu cho nhu cầu của mình một cách chuyên nghiệp!

Nội dung khóa học: www.tuhocr.com

Hành trình ngàn dặm bắt đầu từ bước chân đầu tiên.

ĐĂNG KÝ NGAY: https://www.tuhocr.com/register