messenger_logo
Liên hệ qua Messenger
SciEco

Cập nhật cực chất trên flextable 0.9.11: đồng bộ hóa biểu đồ và trình bày quarto đỉnh cao

I
IEFPA
Ngày viết: 05/06/2026

Thư viện flextable phiên bản mới nhất 0.9.11 đã chính thức xuất hiện trên CRAN, mang lại những cải tiến vượt trội giúp đơn giản hóa quy trình báo cáo dữ liệu của bạn. Trong bản cập nhật lần này, hai tính năng nổi bật nhất chính là sự tích hợp mượt mà với patchwork và khả năng hỗ trợ định dạng Quarto trực tiếp trong từng ô dữ liệu thông qua hàm as_qmd. Hãy cùng khám phá xem những công cụ này sẽ thay đổi cách chúng ta thiết kế các bảng biểu báo cáo khoa học dữ liệu như thế nào.

Tích hợp patchwork: Thiết kế bố cục biểu đồ và bảng số liệu chuyên nghiệp

Trước đây, việc căn chỉnh một bảng số liệu nằm song song hoặc đồng bộ với một biểu đồ thường đòi hỏi rất nhiều công sức căn chỉnh thủ công. Giờ đây, với sự hỗ trợ của patchwork, quy trình này trở nên vô cùng đơn giản. Hàm mới wrap_flextable cho phép biến đổi các đối tượng flextable thành các thành phần có thể dễ dàng ghép nối bằng các toán tử cộng, vạch đứng hoặc gạch chéo của patchwork.

Để minh họa, chúng ta sẽ xây dựng một biểu đồ quả tạ biểu diễn số liệu thống kê của các đội bóng tại giải Bundesliga, sau đó ghép nối nó với một bảng số liệu tương ứng.

Đầu tiên, hãy khởi tạo tập dữ liệu cơ sở:

1dataset <- data.frame(
2  team = c(
3    "FC Bayern Munchen", "SV Werder Bremen", "Borussia Dortmund",
4    "VfB Stuttgart", "Borussia M'gladbach", "Hamburger SV",
5    "Eintracht Frankfurt", "FC Schalke 04", "1. FC Koln",
6    "Bayer 04 Leverkusen"
7  ),
8  matches = c(2000, 1992, 1924, 1924, 1898, 1866, 1856, 1832, 1754, 1524),
9  won     = c(1206,  818,  881,  782,  763,  746,  683,  700,  674,  669),
10  lost    = c( 363,  676,  563,  673,  636,  625,  693,  669,  628,  447)
11)
12dataset$win_pct  <- dataset$won  / dataset$matches * 100
13dataset$loss_pct <- dataset$lost / dataset$matches * 100
14dataset$team <- factor(dataset$team, levels = rev(dataset$team))

Tiếp theo, chúng ta vẽ biểu đồ quả tạ thể hiện tỷ lệ thắng và thua của từng đội bóng:

1pal <- c(lost = "#EFAC00", won = "#28A87D")
2df_long <- reshape(dataset, direction = "long",
3  varying = list(c("loss_pct", "win_pct")),
4  v.names = "pct", timevar = "type",
5  times = c("lost", "won"), idvar = "team"
6)
7p <- ggplot(df_long, aes(x = pct / 100, y = team)) +
8  stat_summary(
9    geom = "linerange", fun.min = "min", fun.max = "max",
10    linewidth = .7, color = "grey60"
11  ) +
12  geom_point(aes(fill = type), size = 4, shape = 21,
13    stroke = .8, color = "white"
14  ) +
15  scale_x_continuous(
16    labels = scales::percent,
17    expand = expansion(add = c(.02, .02))
18  ) +
19  scale_y_discrete(name = NULL, guide = "none") +
20  scale_fill_manual(
21    values = pal,
22    labels = c(lost = "Lost", won = "Won")
23  ) +
24  labs(x = NULL, fill = NULL) +
25  theme(
26    legend.position = "top",
27    legend.justification = "left",
28    panel.grid.minor = element_blank(),
29    panel.grid.major.y = element_blank()
30  )
31p

Bây giờ, chúng ta sẽ tạo một bảng dữ liệu flextable tương ứng để chuẩn bị cho quá trình ghép nối:

1ft_dat <- dataset[, c("matches", "win_pct", "loss_pct", "team")]
2ft_dat$team <- as.character(ft_dat$team)
3ft <- flextable(ft_dat) |>
4  border_remove() |>
5  bold(part = "header") |>
6  colformat_double(j = c("win_pct", "loss_pct"), digits = 1, suffix = "%") |>
7  set_header_labels(team = "Team", matches = "GP", win_pct = "Won", loss_pct = "Lost") |>
8  color(color = c("#28A87D", "#EFAC00"), j = c("win_pct", "loss_pct")) |>
9  italic(j = "team", italic = TRUE, part = "all") |>
10  align(align = "right", part = "all") |>
11  autofit()
12ft

Căn chỉnh các dòng với thuộc tính flex_body

Khi thiết lập thuộc tính flex_body bằng TRUE, các dòng dữ liệu trong phần thân bảng sẽ tự động giãn ra để khớp chính xác với chiều cao của phân vùng biểu đồ bên cạnh. Lúc này, từng dòng của bảng sẽ khớp hoàn hảo với danh mục tương ứng trên trục tung của biểu đồ, tạo nên một chỉnh thể thống nhất cực kỳ chuyên nghiệp. Phần tiêu đề đầu trang và chân trang vẫn giữ nguyên kích thước cố định để đảm bảo tính dễ đọc.

1wrap_flextable(ft, flex_body = TRUE, just = "right") +
2  p +
3  plot_layout(widths = c(1.1, 2))

Với cách tiếp cận này, bảng số liệu và biểu đồ hòa làm một, giúp người xem dễ dàng đối chiếu số liệu chi tiết ngay bên cạnh các điểm trực quan hóa.

Căn chỉnh các cột với thuộc tính flex_cols

Tương tự như việc căn chỉnh dòng, khi chúng ta đặt thuộc tính flex_cols bằng TRUE, các cột dữ liệu sẽ tự động giãn rộng để lấp đầy chiều rộng của phân vùng được xác định bởi biểu đồ lân cận. Mỗi cột của bảng sẽ nằm thẳng hàng với danh mục tương ứng trên trục hoành của biểu đồ cột phía dưới.

Hãy cùng thực hiện ví dụ thực tế dưới đây để thấy rõ sự tiện lợi này:

1cyl_mpg <- mtcars |>
2  mutate(
3    cyl = factor(cyl, levels = c(4, 6, 8), labels = c("4-cyl", "6-cyl", "8-cyl"))
4  ) |>
5  summarise(
6    `mpg mean` = mean(mpg, na.rm = TRUE),
7    `mpg sd` = sd(mpg, na.rm = TRUE),
8    n = n(),
9    .by = c(cyl)
10  )
11gg_bar <- ggplot(cyl_mpg, aes(cyl, `mpg mean`)) +
12  geom_col(fill = "#28A87D", width = 0.7) +
13  labs(x = "Cylinders", y = "Mean MPG") +
14  theme(axis.text.x = element_blank())
15cyl_pivoted <- cyl_mpg |>
16  pivot_longer(
17    cols = where(is.numeric)
18  ) |>
19  pivot_wider(
20    id_cols = name,
21    names_from = cyl, values_from = value,
22    names_sort = TRUE
23  )
24set_flextable_defaults(border.color = "#28A87D")
25ft_cyl <- flextable(cyl_pivoted) |>
26  set_header_labels(name = "") |>
27  align(align = "center", part = "all") |>
28  align(align = "right", j = 1, part = "all") |>
29  colformat_double(i = 1:2, digits = 2) |>
30  colformat_double(i = 3, digits = 0) |>
31  autofit()
32wrap_flextable(ft_cyl, n_row_headers = 1, flex_cols = TRUE) /
33  gg_bar +
34  plot_layout(heights = c(1, 4))

Sự đồng bộ hoàn hảo giữa biểu đồ cột và các cột số liệu phía trên tạo ra trải nghiệm đọc báo cáo liền mạch và rõ ràng hơn bao giờ hết.

Trình bày mã nguồn Quarto trực tiếp trong ô dữ liệu

Trước phiên bản này, flextable chưa hỗ trợ định dạng markdown bên trong các ô dữ liệu. Điều này đồng nghĩa với việc bạn không thể chèn các liên kết, công thức toán học hay thực hiện tham chiếu chéo trong tài liệu Quarto một cách trực tiếp. Hàm mới as_qmd đã giải quyết triệt để hạn chế này.

Tính năng as_qmd hoạt động tương thích với nhiều định dạng đầu ra bao gồm HTML, PDF và tài liệu Word.

Để bắt đầu sử dụng tính năng này trong một dự án Quarto, trước tiên bạn cần cài đặt phần mở rộng lọc Lua đồng hành bằng cách chạy lệnh use_flextable_qmd, sau đó khai báo bộ lọc này trong phần cấu hình YAML của tài liệu.

Dưới đây là một ví dụ về cấu trúc mã nguồn khi sử dụng as_qmd để định dạng văn bản và tham chiếu chéo ngay bên trong các ô của bảng:

1# Cau hinh bo loc YAML trong file Quarto (.qmd)
2# filters:
3#   - flextable-qmd
4#   - at: post-render
5#     path: _extensions/flextable-qmd/unwrap-float.lua
6# Doan ma nguon R trien khai trong tai lieu Quarto:
7library(flextable)
8dat <- data.frame(
9  Feature = c("Tham chieu cheo", "Dinh dang chu", "Cong thuc toan", "Lien ket"),
10  Demo = c(
11    "Xem tai Table tbl-example",
12    "van ban quan trong",
13    "E = mc^2",
14    "ardata.fr"
15  ),
16  stringsAsFactors = FALSE
17)
18flextable(dat) |>
19  mk_par(j = "Demo",
20    value = as_paragraph(as_qmd(Demo))) |>
21  autofit() |>
22  theme_vanilla()

Việc kết xuất ra định dạng tài liệu Word giờ đây trở nên vô cùng trực quan và lưu giữ trọn vẹn các định dạng mong muốn ngay trong bảng biểu của bạn.

✨ Giá trị đắt giá

Sự kết hợp giữa wrap_flextable và patchwork giúp xóa nhòa ranh giới giữa bảng số liệu tĩnh và biểu đồ động. Thay vì tạo ra hai phần độc lập, giờ đây bạn có thể hợp nhất chúng thành một sản phẩm truyền thông dữ liệu duy nhất, đồng bộ tuyệt đối về mặt thị giác. Điều này không chỉ nâng cao tính thẩm mỹ mà còn giúp giảm thiểu đáng kể thời gian thiết kế báo cáo thủ công cho các nhà phân tích dữ liệu.

Câu hỏi tư duy hoặc bài tập ứng dụng

Hãy thử áp dụng hàm wrap_flextable vào tập dữ liệu hiện tại của bạn. Bạn sẽ lựa chọn phương án đồng bộ dòng flex_body hay đồng bộ cột flex_cols để tối ưu hóa khả năng truyền tải thông tin của báo cáo? Hãy chia sẻ thiết kế của bạn và những cải thiện về mặt thời gian xử lý mà tính năng mới này mang lại.


Bài viết khác
Dữ liệu mạng xã hội đã trở thành một nguồn tài nguyên vô giá cho các nghiên cứu xã hội học, hành vi người dùng và phân tích thị trường. Bên cạnh các nguồn dữ liệu truyền thống, việc thu thập thông tin từ Facebook luôn là mục tiêu quan trọng của các nhà nghiên cứu dữ liệu. Để hỗ trợ quá trình này, công cụ facebook2stata được phát triển nhằm giúp người dùng kết nối trực tiếp Stata với hệ thống dữ liệu của Facebook. Bài viết này sẽ hướng dẫn chi tiết cách cài đặt, cấu hình mã xác thực và thực hiện các truy vấn cơ bản từ Facebook vào môi trường làm việc của Stata. Cài đặt công cụ facebook2stata Để bắt đầu, bạn cần cài đặt gói lệnh facebook2stata từ máy chủ của Stata. Việc cài đặt vô cùng đơn giản bằng cách khởi chạy dòng lệnh sau trong cửa sổ dòng lệnh của phần mềm.
Phương pháp ước lượng tối đa khả dĩ mục tiêu thường được gọi là TMLE là một công cụ mạnh mẽ trong phân tích nhân quả. Nhiều nhà nghiên cứu từng nghe về đặc tính song trùng bền vững của phương pháp này nhưng chỉ thực sự thấu hiểu nó khi tiến hành giả lập dữ liệu thực tế. Phương pháp này hoạt động cực kỳ hiệu quả khi một trong hai mô hình kết quả hoặc mô hình điều trị được thiết lập chính xác. Việc kết hợp thuật toán XGBoost cùng TMLE giúp tự động bắt trọn các mối quan hệ phức tạp trong dữ liệu mà không cần phải khai báo các tương tác thủ công. Bài viết này sẽ đi sâu vào cơ chế vận hành của phương pháp thông qua việc giả lập dữ liệu cụ thể trong môi trường R. Khái Niệm Về Tmle TMLE là một phương pháp thống kê tiên tiến được sử dụng để ước lượng các tác động nhân quả trong các nghiên cứu quan sát và thử nghiệm lâm sàng. Phương pháp này kết hợp linh hoạt giữa các thuật toán học máy và kỹ thuật thống kê truyền thống nhằm mang lại các ước lượng vững cho hiệu quả tác động của can thiệp, đồng thời kiểm soát tốt các yếu tố nhiễu. Quy trình vận hành của TMLE gồm hai giai đoạn chính. Đầu tiên, hệ thống sẽ ước lượng mô hình kết quả và mô hình điều trị. Sau đó, các ước lượng này được sử dụng để hiệu chỉnh nhằm hướng trực tiếp đến tham số mục tiêu cần nghiên cứu. Cách tiếp cận này đặc biệt hữu ích trong các bối cảnh mà phương pháp truyền thống dễ bị lệch hoặc hoạt động kém hiệu quả do sự xuất hiện của các mối quan hệ phi tuyến phức tạp.
SciEco
Science for Economics
Định hướng đào tạo phân tích dữ liệu, xây dựng chính sách, tối ưu hoá danh mục tài chính cá nhân và dự báo thị trường.
Liên hệ
Địa chỉ: Số 60, ngõ 41, Phố Thái Hà, Trung Liệt, Đống Đa, Hà Nội (Google Map)
Email: science.for.economics@gmail.com
Hotline: 03.57.94.7680 (Mrs. Hà)
Mạng xã hội