Chuyển đến nội dung chính
R
Dịch vụ Nghề nghiệp

40 Câu hỏi & Trả lời Phỏng vấn Lập trình R cho Mọi Cấp độ

Tìm hiểu 40 câu hỏi phỏng vấn lập trình R cơ bản và đáp án cho mọi cấp độ thâm niên: câu hỏi cho cấp cơ bản, trung cấp và nâng cao.
Elena Kosourova's photo
Elena Kosourova
Đã cập nhật · 15 phút đọc

Khám phá cùng AI

ChatGPTClaudePerplexity

Tạo tài khoản miễn phí của bạn

Luyện tập và Lộ trình tiến trình của bạn.

Tiếp Tục Với Google
Bằng cách tiếp tục, bạn chấp nhận Điều khoản sử dụng, Chính sách bảo mật và việc dữ liệu của bạn được lưu trữ tại Hoa Kỳ.

Để tăng cơ hội thành công trong buổi phỏng vấn R, việc biết trước những câu hỏi tiềm năng luôn hữu ích—dù bạn là ứng viên đang tìm việc hay là nhà tuyển dụng/nhà quản lý tuyển dụng muốn đặt câu hỏi cho ứng viên.

Bài viết này thảo luận 40 câu hỏi phỏng vấn lập trình R cơ bản cùng câu trả lời cho mọi cấp độ thâm niên, cũng như một số câu hỏi phỏng vấn tổng quát. Để tiện theo dõi, tất cả câu hỏi kỹ thuật được chia làm ba mức: cơ bản (entry-level), trung cấp và nâng cao.

Là tài liệu bổ trợ cho việc chuẩn bị phỏng vấn lập trình R, hãy tham khảo các blog và khóa học hữu ích sau:

Câu hỏi Phỏng vấn Tổng quát về Lập trình R

Ở phần đầu buổi phỏng vấn R, người phỏng vấn có thể hỏi ứng viên vài câu hỏi tổng quát, không kỹ thuật về trải nghiệm chung với R. Ví dụ:

  • Bạn đã làm việc với R bao lâu rồi?
  • Bạn thực hiện những loại tác vụ nào trong R?
  • Bạn tự đánh giá mức độ thành thạo R của mình như thế nào?

Nếu bạn là ứng viên, hãy nghĩ trước về những câu hỏi như vậy và chuẩn bị câu trả lời. Đừng lo nếu bạn chưa có kinh nghiệm làm việc thực tế với R: mô tả kỳ thực tập về lập trình R hoặc các dự án R cá nhân/nhóm bạn đã hoàn thành trong quá trình học cũng ổn.

Hơn nữa, nếu bạn phỏng vấn cho vị trí entry-level, người phỏng vấn không nhất thiết kỳ vọng bạn có kinh nghiệm làm việc dày dặn (thậm chí là chưa có) với R. Hãy nhớ rằng việc bạn được mời phỏng vấn cho thấy công ty đã thấy hồ sơ của bạn hấp dẫn.

Câu hỏi Phỏng vấn Lập trình R Cấp Cơ bản

Hãy bắt đầu với một số câu hỏi kỹ thuật cơ bản về R mà bạn có thể gặp từ nhà tuyển dụng tiềm năng. Những câu hỏi này yêu cầu bạn nắm vững nền tảng và có chút kinh nghiệm thực hành với R.

1. R là gì và các đặc điểm chính của nó?

R là một ngôn ngữ lập trình và môi trường được dùng rộng rãi để giải quyết các bài toán khoa học dữ liệu, được thiết kế đặc biệt cho tính toán thống kê và trực quan hóa dữ liệu. Các đặc điểm chính gồm:

  • Mã nguồn mở
  • Thông dịch (tức hỗ trợ cả lập trình hàm và hướng đối tượng)
  • Rất dễ mở rộng nhờ bộ sưu tập lớn các gói khoa học dữ liệu
  • Hàm tính và linh hoạt (người dùng có thể định nghĩa hàm riêng, cũng như tinh chỉnh nhiều tham số của các hàm hiện có)
  • Tương thích với nhiều hệ điều hành
  • Dễ dàng tích hợp với các ngôn ngữ và framework khác
  • Cho phép tính toán thống kê mạnh mẽ
  • Cung cấp nhiều công cụ trực quan hóa để tạo biểu đồ chất lượng xuất bản
  • Trang bị giao diện dòng lệnh
  • Được hỗ trợ bởi cộng đồng trực tuyến mạnh mẽ

2. Một số nhược điểm khi dùng R là gì?

  • Cú pháp không trực quan và vì vậy đường cong học tập dốc, đặc biệt với người mới lập trình
  • Tương đối chậm
  • Sử dụng bộ nhớ kém hiệu quả
  • Tài liệu của các gói không nhất quán và thường khó đọc
  • Một số gói chất lượng thấp hoặc bảo trì kém
  • Có thể có lo ngại về bảo mật do tính mã nguồn mở

3. Liệt kê và định nghĩa một số kiểu dữ liệu cơ bản trong R.

Có một vài kiểu dữ liệu trong R, bao gồm: 

  1. Numeric—các số thập phân.
  2. Integer—các số nguyên.
  3. Character—một chữ cái, số, hoặc ký hiệu, hoặc bất kỳ tổ hợp nào của chúng, đặt trong dấu ngoặc kép đôi hoặc đơn.
  4. Factor—các hạng mục (mức) từ một tập giá trị khả dĩ được xác định trước, thường có thứ tự nội tại.
  5. Logical—các giá trị Boolean TRUE và FALSE, biểu diễn ngầm là 1 và 0 tương ứng.

4. Liệt kê và định nghĩa một số cấu trúc dữ liệu cơ bản trong R.

  1. Vector—cấu trúc một chiều dùng để lưu các giá trị cùng kiểu dữ liệu.
  2. List—cấu trúc đa chiều dùng để lưu các giá trị của bất kỳ kiểu dữ liệu nào và/hoặc các cấu trúc dữ liệu khác.
  3. Matrix—cấu trúc hai chiều dùng để lưu các giá trị cùng kiểu dữ liệu.
  4. Data frame—cấu trúc hai chiều dùng để lưu các giá trị thuộc bất kỳ kiểu dữ liệu nào, nhưng mỗi cột phải lưu các giá trị cùng kiểu.

5. Cách nhập dữ liệu trong R?

Base R cung cấp các hàm thiết yếu để nhập dữ liệu:

  • read.table()—hàm tổng quát nhất của base R để nhập dữ liệu, nhận dữ liệu dạng bảng với mọi loại ký tự phân tách trường, kể cả các ký tự cụ thể như |.

  • read.csv()—tệp CSV (comma-separated values) với . làm dấu thập phân.

  • read.csv2()—tệp phân tách bằng dấu chấm phẩy, với , làm dấu thập phân.

  • read.delim()—tệp TSV (tab-separated values) với . làm dấu thập phân.

  • read.delim2()—tệp TSV với , làm dấu thập phân.

Trong thực tế, bất kỳ hàm nào trong số này cũng có thể dùng để nhập dữ liệu dạng bảng với mọi kiểu phân tách trường và dấu thập phân: việc dùng cho định dạng tệp cụ thể chỉ là vấn đề quy ước và thiết lập mặc định. Ví dụ, cú pháp của hàm đầu tiên là: read.table(file, header = FALSE, sep = "", dec = "."). Các hàm khác có cùng tham số với cài đặt mặc định khác nhau, luôn có thể ghi đè tường minh.

Các gói tidyverse readr và readxl cung cấp thêm một số hàm để nhập các định dạng tệp cụ thể. Mỗi hàm trong số đó có thể tinh chỉnh thêm bằng cách đặt nhiều tham số tùy chọn.

readr

  • read_tsv()—tệp TSV.

  • read_fwf()—tệp có độ rộng cột cố định.

  • read_log()—tệp nhật ký web.

  • read_table(), read_csv(), read_csv2() và read_delim()—tương đương với các hàm của base R.

readxl

  • read_excel()—tệp Excel.

  • read_csv()—tương đương với hàm trong base R.

Để tìm hiểu sâu hơn về nạp dữ liệu trong R, bạn có thể xem hướng dẫn Cách nhập dữ liệu vào R.

6. Gói (package) trong R là gì, và cách cài đặt, nạp gói?

Một gói R là tập hợp các hàm, mã, dữ liệu và tài liệu, đại diện cho phần mở rộng của ngôn ngữ R và được thiết kế để giải quyết các loại tác vụ cụ thể. R có sẵn một số gói được cài đặt trước, và người dùng có thể cài thêm gói từ các kho lưu trữ. Kho tập trung phổ biến nhất lưu trữ hàng nghìn gói R khác nhau là Comprehensive R Archive Network (CRAN).

Để cài một gói R trực tiếp từ CRAN, ta cần truyền tên gói đặt trong dấu ngoặc kép cho hàm install.packages(), như sau: install.packages("package_name"). Để cài nhiều gói từ CRAN trong một lần, ta dùng một vector ký tự chứa các tên gói đặt trong ngoặc kép, như sau: install.packages(c("package_name_1", "package_name_2"). Để cài gói R thủ công, trước hết ta tải gói dưới dạng tệp zip về máy tính rồi chạy install.packages() function:

install.packages("path_to_the_locally_stored_zipped_package_file", repos=NULL, type="source")

Để nạp một gói R đã cài vào môi trường làm việc, ta có thể dùng hàm library() hoặc require(). Mỗi hàm nhận tên gói không có ngoặc kép và nạp gói, ví dụ, library(caret). Tuy nhiên, hành vi khác nhau khi không tìm thấy gói cần thiết: library() ném lỗi và dừng chạy chương trình, còn require() đưa ra cảnh báo và tiếp tục chạy.

7. Cách tạo data frame trong R?

1. Từ một hoặc nhiều vector có cùng độ dài—dùng hàm data.frame():

df <- data.frame(vector_1, vector_2)

2. Từ một ma trận—dùng hàm data.frame():

df <- data.frame(my_matrix)

3. Từ một danh sách vector có cùng độ dài—dùng hàm data.frame():

df <- data.frame(list_of_vectors)

4. Từ các data frame khác:

  • Gộp các data frame theo chiều ngang (chỉ khi các data frame có cùng số hàng, và các bản ghi giống nhau theo cùng thứ tự)—dùng hàm cbind():

df <- cbind(df1, df2)
  • Gộp các data frame theo chiều dọc (chỉ khi chúng có cùng số lượng cột trùng tên, cùng kiểu dữ liệu và xuất hiện theo cùng thứ tự)—dùng hàm rbind():

df <- rbind(df1, df2)

8. Cách thêm cột mới vào data frame trong R?

  1. Dùng ký hiệu $:
df <- data.frame(col_1=10:13, col_2=c("a", "b", "c", "d"))
print(df)
​
df$col_3 <- c(5, 1, 18, 16)
print(df)

Output:

  col_1 col_2
1    10     a
2    11     b
3    12     c
4    13     d
  col_1 col_2 col_3
1    10     a     5
2    11     b     1
3    12     c    18
4    13     d    16
  1. Dùng ngoặc vuông:
df <- data.frame(col_1=10:13, col_2=c("a", "b", "c", "d"))
print(df)
​
df["col_3"] <- c(5, 1, 18, 16)
print(df)

Output:

  col_1 col_2
1    10     a
2    11     b
3    12     c
4    13     d
  col_1 col_2 col_3
1    10     a     5
2    11     b     1
3    12     c    18
4    13     d    16
  1. Dùng hàm cbind():

df <- data.frame(col_1=10:13, col_2=c("a", "b", "c", "d"))
print(df)
​
df <- cbind(df, col_3=c(5, 1, 18, 16))
print(df)

Output:

 col_1 col_2
1    10     a
2    11     b
3    12     c
4    13     d
  col_1 col_2 col_3
1    10     a     5
2    11     b     1
3    12     c    18
4    13     d    16

Trong cả ba trường hợp, ta có thể gán một giá trị đơn lẻ hoặc một vector, hoặc tính toán cột mới dựa trên các cột hiện có của data frame đó hoặc các data frame khác.

9. Cách xóa cột khỏi data frame trong R?

1. Dùng hàm select() của gói dplyr thuộc bộ tidyverse. Tên mỗi cột muốn xóa được truyền vào với dấu trừ đứng trước:

df <- select(df, -col_1, -col_3)

Nếu có quá nhiều cột cần xóa, hợp lý hơn là giữ lại các cột còn lại thay vì liệt kê cột cần xóa. Khi đó, cú pháp tương tự, nhưng tên các cột cần giữ lại không có dấu trừ:

df <- select(df, col_2, col_4)

2. Dùng hàm dựng sẵn subset() của base R. Nếu cần xóa một cột, ta gán cho tham số select của hàm tên cột với dấu trừ phía trước. Để xóa nhiều cột, ta gán cho tham số này một vector chứa các tên cột có dấu trừ phía trước:

df <- subset(df, select=-col_1)
df <- subset(df, select=-c(col_1, col_3))

Nếu có quá nhiều cột cần xóa, hợp lý hơn là giữ lại các cột còn lại thay vì xóa các cột quan tâm. Khi đó, cú pháp tương tự, nhưng không thêm dấu trừ:

df <- subset(df, select=col_2)
df <- subset(df, select=c(col_2, col_4))

10. Factor trong R là gì?

Factor trong R là một kiểu dữ liệu đặc thù chấp nhận các hạng mục (còn gọi là mức) từ một tập giá trị khả dĩ được xác định trước. Các hạng mục này trông như kiểu ký tự nhưng bên trong được lưu dưới dạng số nguyên. Thường các hạng mục như vậy có thứ tự nội tại. Ví dụ, một cột trong data frame chứa các mức thang đo Likert để đánh giá quan điểm ("hoàn toàn đồng ý", "đồng ý", "hơi đồng ý", "không đồng ý cũng không phản đối", "hơi phản đối", "phản đối", "hoàn toàn phản đối") nên để kiểu factor để nắm bắt thứ tự này và phản ánh đúng trên các biểu đồ dữ liệu phân loại.

11. RStudio là gì?

RStudio là IDE (môi trường phát triển tích hợp) mã nguồn mở, được dùng rộng rãi làm giao diện đồ họa để làm việc với ngôn ngữ R từ phiên bản 3.0.1. Nó có nhiều tính năng hữu ích khiến RStudio rất phổ biến trong cộng đồng R:

  • Thân thiện với người dùng
  • Linh hoạt
  • Đa chức năng
  • Cho phép tạo script có thể tái sử dụng
  • Theo dõi lịch sử thao tác
  • Tự động hoàn thành mã
  • Cung cấp trợ giúp chi tiết, đầy đủ cho mọi đối tượng
  • Truy cập dễ dàng mọi dữ liệu đã nhập và đối tượng đã tạo
  • Dễ dàng chuyển đổi giữa terminal và console
  • Cho phép xem trước biểu đồ
  • Hỗ trợ tạo và chia sẻ dự án hiệu quả
  • Có thể dùng với các ngôn ngữ khác (Python, SQL, v.v.)

Để tìm hiểu thêm RStudio là gì, cách cài đặt và bắt đầu sử dụng, bạn có thể theo dõi Hướng dẫn RStudio.

12. R Markdown là gì?

R Markdown là một gói R miễn phí và mã nguồn mở cung cấp khung soạn thảo cho việc xây dựng các dự án khoa học dữ liệu. Với nó, ta có thể viết một tệp .rmd kết hợp phần thuyết minh, mã và biểu đồ, rồi kết xuất tệp này ra định dạng đầu ra đã chọn. Đặc điểm chính của R Markdown gồm:

  • Tài liệu tạo ra có thể chia sẻ, tái lập đầy đủ và đạt chất lượng xuất bản.
  • Phạm vi rộng các đầu ra và định dạng tĩnh/động như HTML, PDF, Microsoft Word, tài liệu tương tác, dashboard, báo cáo, bài viết, sách, thuyết trình, ứng dụng, trang web, mẫu tái sử dụng, v.v.
  • Dễ dàng theo dõi kiểm soát phiên bản.
  • Hỗ trợ nhiều ngôn ngữ lập trình, bao gồm R, Python và SQL.

13. Cách tạo hàm do người dùng định nghĩa trong R?

Để tạo hàm do người dùng định nghĩa trong R, ta dùng từ khóa function và cú pháp sau:

function_name <- function(parameters){
    function body 
}
  1. Tên hàm—tên đối tượng hàm sẽ được dùng để gọi sau khi định nghĩa.
  2. Tham số hàm—các biến, phân tách bằng dấu phẩy và đặt trong ngoặc tròn, sẽ được gán giá trị đối số mỗi lần gọi hàm.
  3. Thân hàm—khối mã trong ngoặc nhọn chứa các thao tác sẽ thực hiện theo thứ tự định trước trên các đối số mỗi lần gọi. Thường thân hàm chứa câu lệnh return() trả về kết quả, hoặc câu lệnh print() để in kết quả.

Ví dụ về một hàm đơn giản do người dùng định nghĩa trong R:

my_function <- function(x, y){
    return(x + y)
}

14. Liệt kê một số gói trực quan hóa dữ liệu phổ biến trong R.

  • ggplot2—gói trực quan hóa dữ liệu R phổ biến nhất, cho phép tạo đa dạng biểu đồ.
  • Lattice—để hiển thị dữ liệu đa biến dưới dạng các ô (trellis) của nhiều biểu đồ.
  • Plotly—để tạo biểu đồ tương tác, chất lượng xuất bản.
  • highcharter—để vẽ động dễ dàng, nhiều tính năng linh hoạt, plugin và chủ đề; cho phép biểu diễn nhiều đối tượng R chỉ với một hàm.
  • Leaflet—để tạo bản đồ tương tác.
  • ggvis—để tạo biểu đồ tương tác, tùy biến cao, có thể truy cập trên bất kỳ trình duyệt nào bằng hạ tầng Shiny.
  • patchwork—để kết hợp nhiều biểu đồ, thường là các loại khác nhau, trên cùng một hình.

Câu hỏi Phỏng vấn Lập trình R Cấp Trung

Với những người có kinh nghiệm hơn, nhiều khả năng người phỏng vấn sẽ hỏi các câu cần kiến thức chi tiết hơn về R. Dưới đây là một số câu để bạn chuẩn bị:

15. Cách gán giá trị cho biến trong R?

  1. Dùng toán tử gán <-, ví dụ, my_var <- 1—cách phổ biến nhất để gán giá trị cho biến trong R.

  2. Dùng toán tử bằng =, ví dụ, my_var = 1—để gán giá trị cho đối số bên trong định nghĩa hàm.

  3. Dùng toán tử gán sang phải ->, ví dụ, my_var -> 1—có thể dùng trong pipe.

  4. Dùng toán tử gán toàn cục, sang trái (<<-) hoặc sang phải (->>), ví dụ, my_var <<- 1—để tạo biến toàn cục bên trong định nghĩa hàm.

16. Quy tắc đặt tên biến trong R là gì?

  • Tên biến có thể là kết hợp của chữ cái, chữ số, dấu chấm và gạch dưới. Không được chứa ký tự khác, kể cả khoảng trắng.

  • Tên biến phải bắt đầu bằng chữ cái hoặc dấu chấm.

  • Nếu tên bắt đầu bằng dấu chấm, ký tự theo sau không được là chữ số.

  • Từ khóa dành riêng trong R (TRUE, for, NULL, v.v.) không được dùng làm tên biến.

  • Tên biến phân biệt chữ hoa/chữ thường.

Trong khóa học Viết mã R hiệu quả, bạn sẽ tìm thấy nhiều thực hành tốt hơn cho việc viết mã trong R.

17. Có những loại vòng lặp nào trong R và cú pháp của từng loại?

1. Vòng lặp for—lặp qua một dãy với số lần bằng độ dài của nó (trừ khi dùng các câu lệnh break và/hoặc next) và thực hiện cùng một tập thao tác trên mỗi phần tử. Đây là loại vòng lặp phổ biến nhất. Cú pháp của vòng lặp for trong R:

for (variable in sequence) {
    operations
}

2. Vòng lặp while—thực hiện cùng một tập thao tác cho đến khi một điều kiện logic định sẵn (hoặc nhiều điều kiện) thỏa mãn—trừ khi dùng break và/hoặc next. Khác với for, ta không biết trước số vòng lặp while sẽ chạy. Trước khi chạy while, ta cần gán giá trị cho biến (hoặc nhiều biến) và cập nhật biến đó trong thân vòng lặp ở mỗi lần lặp. Cú pháp của while trong R:

variable assignment

while (logical condition) {
    operations
    variable update
}

3. Vòng lặp repeat—lặp lại cùng một tập thao tác cho đến khi thỏa điều kiện dừng (break) định sẵn (hoặc nhiều điều kiện). Để đưa điều kiện như vậy vào, repeat phải chứa khối if, và trong đó phải có câu lệnh break. Giống while, ta không biết trước số vòng lặp repeat sẽ chạy. Cú pháp của repeat trong R:

repeat { 
    operations 
    if(break condition) {
        break
    }
}

Bạn có thể đọc thêm về Vòng lặp trong R với hướng dẫn riêng.

18. Cách tổng hợp dữ liệu trong R?

Để tổng hợp dữ liệu trong R, ta dùng hàm aggregate(). Hàm này có các tham số thiết yếu sau, theo thứ tự:

  • x—data frame cần tổng hợp.

  • by—một danh sách các factor để nhóm theo.

  • FUN—một hàm tổng hợp để tính thống kê tóm tắt cho mỗi nhóm (ví dụ, mean, max, min, count, sum).

19. Cách gộp dữ liệu trong R?

1. Dùng hàm cbind()—chỉ khi các data frame có cùng số hàng, và các bản ghi giống nhau theo cùng thứ tự:

df <- cbind(df1, df2)

2. Dùng hàm rbind() để gộp theo chiều dọc—chỉ khi chúng có cùng số lượng cột trùng tên, cùng kiểu dữ liệu và xuất hiện theo cùng thứ tự:

df <- rbind(df1, df2)

3. Dùng hàm merge() để gộp theo cột chung, thường là cột ID:

  • Inner join:
df <- merge(df1, df2, by="ID")
  • Left join:
df <- merge(df1, df2, by="ID", all.x=TRUE)
  • Right join:
df <- merge(df1, df2, by="ID", all.y=TRUE)
  • Outer join:
df <- merge(df1, df2, by="ID", all=TRUE)

4. Dùng hàm join() của gói dplyr để gộp theo cột chung, thường là ID:

df <- join(df1, df2, by="ID", type="type_of_join")

Tham số type nhận một trong các giá trị: inner, left, right hoặc full.

20. Cách nối chuỗi trong R?

Ta có thể nối hai hoặc nhiều chuỗi trong R bằng hàm paste() hoặc cat(). Cách đầu phổ biến hơn. Cả hai nhận vào số lượng chuỗi bất kỳ để ghép và có thể nhận tham số tùy chọn sep (cùng các tham số tùy chọn khác)—một ký tự hoặc chuỗi ký tự để phân tách các chuỗi trong kết quả (mặc định là khoảng trắng).

21. Cách chuyển vị dữ liệu hai chiều trong R?

Ta có thể chuyển vị data frame hoặc ma trận trong R sao cho các cột trở thành hàng và ngược lại. Mục đích này dùng hàm t() của base R. Ví dụ:

df <- data.frame(col_1=c(10, 20, 30), col_2=c(11, 22, 33))
print(df)
​
transposed_df <- t(df)
print(transposed_df)

Output:

 col_1 col_2
1    10    11
2    20    22
3    30    33
      [,1] [,2] [,3]
col_1   10   20   30
col_2   11   22   33

22. Cách xâu chuỗi nhiều thao tác trong R?

Ta có thể xâu chuỗi nhiều thao tác trong R bằng toán tử pipe (%>%) do bộ tidyverse cung cấp. Dùng toán tử này cho phép tạo pipeline các hàm, trong đó đầu ra của hàm trước trở thành đầu vào của hàm sau, cho tới khi kết thúc pipeline. Điều này loại nhu cầu tạo biến phụ và tăng đáng kể khả năng đọc mã.

Ví dụ dùng pipe trên một data frame:

df <- data.frame(a=1:4, b=11:14, c=21:24)
print(df)
​
df_new <- df %>% select(a, b) %>% filter(a > 2)
print(df_new)

Output:

 a  b  c
1 1 11 21
2 2 12 22
3 3 13 23
4 4 14 24
  a  b
1 3 12
2 4 13

23. Có thể tạo những loại biểu đồ nào trong R?

Vì trực quan hóa dữ liệu là một điểm mạnh của R, ta có thể tạo mọi loại biểu đồ trong R:

  • Các loại biểu đồ phổ biến:
    • Biểu đồ cột—hiển thị giá trị số của dữ liệu phân loại.
    • Biểu đồ đường—hiển thị sự thay đổi của một biến, thường theo thời gian.
    • Biểu đồ phân tán—hiển thị mối quan hệ giữa hai biến.
    • Biểu đồ vùng—dựa trên biểu đồ đường, vùng dưới đường được tô màu hoặc họa tiết.
    • Biểu đồ tròn—hiển thị tỷ trọng của mỗi hạng mục dữ liệu phân loại trong tổng thể.
    • Box plot—hiển thị tập thống kê mô tả của dữ liệu.
  • Các loại biểu đồ nâng cao:
    • Violin plot—hiển thị cả thống kê mô tả và dạng phân phối của dữ liệu.
    • Heatmap—hiển thị độ lớn của mỗi điểm dữ liệu số trong tập dữ liệu.
    • Treemap—hiển thị giá trị số của dữ liệu phân loại, thường là một phần của tổng thể.
    • Dendrogram—hiển thị phân cấp nội tại và phân cụm của dữ liệu.
    • Bubble plot—hiển thị mối quan hệ giữa ba biến.
    • Hexbin plot—hiển thị mối quan hệ của hai biến số trong tập dữ liệu tương đối lớn.
    • Word cloud—hiển thị tần suất từ trong văn bản đầu vào.
    • Choropleth map—hiển thị thống kê chuyên đề tổng hợp của dữ liệu địa lý.
    • Circular packing chart—hiển thị phân cấp nội tại và giá trị các điểm dữ liệu
    • v.v.

Lộ trình kỹ năng Trực quan hóa Dữ liệu với R sẽ giúp bạn mở rộng tầm nhìn về đồ họa R. Nếu muốn học trực quan hóa dữ liệu trong R trong bối cảnh rộng hơn, hãy khám phá lộ trình nghề nghiệp kỹ lưỡng, thân thiện với người mới bắt đầu Nhà khoa học Dữ liệu với R.

24. Vector recycling trong R là gì?

Nếu ta cố thực hiện một phép toán trên hai vector R có độ dài khác nhau, bộ thông dịch R sẽ phát hiện vector ngắn hơn, tuần hoàn (recycle) các phần tử của nó theo cùng thứ tự cho tới khi độ dài hai vector khớp nhau, rồi mới thực hiện phép toán. Trước khi bắt đầu recycling, bộ thông dịch R sẽ đưa ra cảnh báo về sự không khớp độ dài ban đầu.

Ví dụ, nếu ta chạy phép cộng sau:

c(1, 2, 3, 4, 5) + c(1, 2, 3)

Vector thứ hai, do recycling, sẽ được chuyển thành c(1, 2, 3, 1, 2). Vì vậy, kết quả cuối cùng sẽ là c(2, 4, 6, 5, 7).

Đôi khi vector recycling có lợi (ví dụ khi ta kỳ vọng tính chu kỳ của các giá trị), nhưng thường là không phù hợp và dễ gây hiểu lầm. Vì thế, ta nên cẩn trọng và lưu ý độ dài vector trước khi thực hiện phép toán.

25. Công dụng của câu lệnh next và break trong R?

Câu lệnh next dùng để bỏ qua một lần lặp cụ thể và chuyển sang lần lặp kế tiếp nếu thỏa một điều kiện. Câu lệnh break dùng để dừng và thoát khỏi vòng lặp tại một lần lặp cụ thể nếu thỏa một điều kiện. Khi dùng trong một vòng lặp lồng nhau, câu lệnh này chỉ thoát vòng lặp bên trong đó.

Cả next và break đều có thể dùng trong mọi loại vòng lặp ở R: for, while và repeat. Chúng cũng có thể dùng trong cùng một vòng lặp, ví dụ:

for(i in 1:10) {
    if(i < 5)
        next
    if(i == 8)
        break
    print(i)}

Output:

[1] 5
[1] 6
[1] 7

26. Khác biệt giữa hàm str() và summary() trong R?

Hàm str() trả về cấu trúc của một đối tượng R và thông tin tổng quan về nó, nội dung chính xác phụ thuộc vào cấu trúc dữ liệu của đối tượng. Ví dụ, với một vector, nó trả về kiểu dữ liệu của các phần tử, phạm vi chỉ số và giá trị phần tử (hoặc vài giá trị đầu nếu vector quá dài). Với data frame, nó trả về lớp (data.frame), số quan sát và biến, tên cột, kiểu dữ liệu của từng cột và vài giá trị đầu của mỗi cột.

Hàm summary() trả về thống kê tóm tắt cho một đối tượng R. Thường áp dụng cho data frame và ma trận, trong đó nó trả về giá trị nhỏ nhất, lớn nhất, trung bình, trung vị, và tứ phân vị 1 và 3 cho mỗi cột số; với cột factor, nó trả về số đếm mỗi mức.

27. Khác biệt giữa hàm subset() và sample() trong R?

Hàm subset() trong R dùng để trích xuất hàng và cột từ data frame hoặc ma trận, hoặc phần tử từ vector, dựa trên các điều kiện nhất định, ví dụ: subset(my_vector, my_vector > 10).

Trong khi đó, hàm sample() trong R chỉ áp dụng cho vector. Nó trích mẫu ngẫu nhiên kích thước định sẵn từ các phần tử của vector, có hoặc không hoàn lại. Ví dụ, sample(my_vector, size=5, replace=TRUE)

Câu hỏi Phỏng vấn Lập trình R Nâng cao

28. Cách tạo cột mới trong data frame trong R dựa trên các cột khác?

1. Dùng các hàm transform() và ifelse() của base R:

df <- data.frame(col_1 = c(1, 3, 5, 7),  col_2 = c(8, 6, 4, 2))
print(df)
​
# Thêm cột col_3 vào data frame df
df <- transform(df, col_3 = ifelse(col_1 < col_2, col_1 + col_2, col_1 * col_2))
print(df)

Output:

  col_1 col_2
1     1     8
2     3     6
3     5     4
4     7     2
  col_1 col_2 col_3
1     1     8     9
2     3     6     9
3     5     4    20
4     7     2    14

2. Dùng các hàm with() và ifelse() của base R:

df <- data.frame(col_1 = c(1, 3, 5, 7),  col_2 = c(8, 6, 4, 2))
print(df)
​
# Thêm cột col_3 vào data frame df
df["col_3"] <- with(df, ifelse(col_1 < col_2, col_1 + col_2, col_1 * col_2))
print(df)

Output:

  col_1 col_2
1     1     8
2     3     6
3     5     4
4     7     2
  col_1 col_2 col_3
1     1     8     9
2     3     6     9
3     5     4    20
4     7     2    14

3. Dùng hàm apply() của base R:

df <- data.frame(col_1 = c(1, 3, 5, 7),  col_2 = c(8, 6, 4, 2))
print(df)
​
# Thêm cột col_3 vào data frame df
df["col_3"] <- apply(df, 1, FUN = function(x) if(x[1] < x[2]) x[1] + x[2] else x[1] * x[2])
print(df) 

Output:

  col_1 col_2
1     1     8
2     3     6
3     5     4
4     7     2
  col_1 col_2 col_3
1     1     8     9
2     3     6     9
3     5     4    20
4     7     2    14

4. Dùng hàm mutate() của gói dplyr và hàm ifelse() của base R:

df <- data.frame(col_1 = c(1, 3, 5, 7),  col_2 = c(8, 6, 4, 2))
print(df)
​
# Thêm cột col_3 vào data frame df
df <- mutate(df, col_3 = ifelse(col_1 < col_2, col_1 + col_2, col_1 * col_2))
print(df)

Output:

  col_1 col_2
1     1     8
2     3     6
3     5     4
4     7     2
  col_1 col_2 col_3
1     1     8     9
2     3     6     9
3     5     4    20
4     7     2    14

29. Cách phân tích cú pháp (parse) ngày từ chuỗi biểu diễn ngày trong R?

Để phân tích cú pháp ngày từ chuỗi biểu diễn trong R, ta nên dùng gói lubridate thuộc bộ tidyverse. Gói này cung cấp nhiều hàm để phân tích chuỗi và trích xuất ngày chuẩn dựa trên mẫu ngày ban đầu trong chuỗi. Các hàm gồm ymd(), ymd_hm(), ymd_hms(), dmy(), dmy_hm(), dmy_hms(), mdy(), mdy_hm(), mdy_hms(), v.v., trong đó y, m, d, h, m và s tương ứng với năm, tháng, ngày, giờ, phút và giây.

Ví dụ, nếu ta chạy hàm dmy() và truyền vào chuỗi "05-11-2023", "05/11/2023" hoặc "05.11.2023"—đều biểu diễn cùng một ngày—ta sẽ nhận cùng kết quả: 2023-11-05. Đó là vì trong cả ba trường hợp, dù ký tự phân tách khác nhau, mẫu đều là: ngày, sau đó tháng, sau đó năm.

30. Công dụng của hàm switch() trong R?

Hàm switch() trong R là câu lệnh rẽ nhánh đa hướng, đánh giá một biểu thức so với các phần tử của một danh sách. Cú pháp:

switch(expression, case_1, case_2, case_3....)

Biểu thức truyền vào switch() có thể đánh giá ra số hoặc chuỗi ký tự, và tùy vào đó mà hành vi hàm khác nhau.

1. Nếu biểu thức đánh giá ra số, switch() trả về phần tử trong danh sách dựa trên khớp vị trí (tức chỉ số bằng với số đó). Nếu số lớn hơn số phần tử trong danh sách, switch() trả về NULL. Ví dụ:

switch(2, "circle", "triangle", "square")

Output:

"triangle"

2. Nếu biểu thức đánh giá ra chuỗi ký tự, switch() trả về giá trị dựa trên tên:

switch("red", "green"="apple", "orange"="carot", "red"="tomato", "yellow"="lemon")

Output:

"tomato"

Nếu có nhiều khớp, giá trị khớp đầu tiên được trả về. Cũng có thể thêm một phần tử không tên làm đối số cuối của switch() như một phương án dự phòng mặc định khi không có khớp. Nếu không đặt tùy chọn mặc định này và không có khớp, hàm trả về NULL.

Hàm switch() là lựa chọn hiệu quả thay cho chuỗi if-else dài vì giúp mã bớt lặp lại và dễ đọc hơn. Thông thường, nó dùng để đánh giá một biểu thức duy nhất. Ta vẫn có thể viết các cấu trúc switch lồng nhau phức tạp để đánh giá nhiều biểu thức; tuy nhiên, khi đó switch() nhanh chóng trở nên khó đọc và mất lợi thế chính so với if-else.

31. Khác biệt giữa các hàm apply(), lapply(), sapply() và tapply()?

Dù tất cả các hàm này cho phép lặp qua một cấu trúc dữ liệu mà không dùng vòng lặp và thực hiện cùng một thao tác trên mỗi phần tử, chúng khác nhau về loại đầu vào/đầu ra và chức năng thực hiện.

  • apply()—nhận data frame, ma trận hoặc mảng và trả về vector, list, ma trận hoặc mảng. Hàm có thể áp dụng theo hàng, theo cột hoặc cả hai.

  • lapply()—nhận vector, list hoặc data frame và luôn trả về list. Với đầu vào là data frame, hàm chỉ áp dụng theo cột.

  • sapply()—nhận vector, list hoặc data frame và trả về cấu trúc dữ liệu đơn giản nhất: vector cho đầu vào vector, list cho đầu vào list, và ma trận cho đầu vào data frame.

  • tapply()—tính thống kê tóm tắt cho các factor (tức dữ liệu phân loại) khác nhau.

32. Liệt kê và định nghĩa các câu lệnh điều khiển trong R.

Có ba nhóm câu lệnh điều khiển trong R: câu lệnh rẽ nhánh, câu lệnh vòng lặp và câu lệnh nhảy.

Câu lệnh rẽ nhánh:

  • if—kiểm tra điều kiện cho trước có đúng không và cung cấp thao tác để thực hiện nếu đúng.

  • if-else—kiểm tra điều kiện cho trước có đúng không, cung cấp thao tác nếu đúng và một tập thao tác khác nếu sai.

  • if... else if... else—kiểm tra tuần tự một loạt điều kiện, cung cấp thao tác cho mỗi điều kiện nếu đúng, và một tập thao tác dự phòng nếu không điều kiện nào đúng.

  • switch—đánh giá một biểu thức so với các phần tử của danh sách và trả về giá trị từ danh sách dựa trên kết quả đánh giá.

Câu lệnh vòng lặp:

  • for—trong vòng lặp for, lặp qua một dãy.

  • while—trong vòng lặp while, kiểm tra điều kiện logic (hoặc nhiều điều kiện) định sẵn tại lần lặp hiện tại.

  • repeat—trong vòng lặp repeat, tiếp tục thực hiện cùng một tập thao tác cho đến khi thỏa điều kiện dừng định sẵn.

Câu lệnh nhảy:

  • next—bỏ qua một lần lặp cụ thể và chuyển sang lần tiếp theo nếu thỏa điều kiện.

  • break—dừng và thoát vòng lặp tại một lần lặp cụ thể nếu thỏa điều kiện.

  • return—thoát khỏi hàm và trả về kết quả.

33. Biểu thức chính quy (regular expressions) là gì và làm việc với chúng trong R như thế nào?

Biểu thức chính quy, hay regex, trong R hoặc ngôn ngữ khác, là một ký tự hoặc chuỗi ký tự mô tả một mẫu văn bản nhất định và dùng để khai thác dữ liệu văn bản. Trong R, có hai cách chính để làm việc với regex:

  1. Dùng base R và các hàm của nó (như grep(), regexpr(), gsub(), regmatches(), v.v.) để định vị, khớp, trích xuất và thay thế regex.
  2. Dùng gói chuyên biệt stringr thuộc bộ tidyverse. Đây là cách tiện lợi hơn vì các hàm của stringr có tên gọi và cú pháp trực quan hơn và cung cấp chức năng phong phú hơn.

Hướng dẫn Biểu thức Chính quy trong R cung cấp chi tiết hơn về cách làm việc với regex trong R.

34. Những gói nào được dùng cho machine learning trong R?

  • caret—cho nhiều thuật toán phân loại và hồi quy.
  • e1071—cho SVM, phân loại naive Bayes, phân cụm bagged, phân cụm mờ và KNN.
  • kernlab—cung cấp các phương pháp dựa trên kernel cho phân loại, hồi quy và phân cụm.
  • randomForest—cho thuật toán rừng ngẫu nhiên phân loại và hồi quy.
  • xgboost—cho gradient boosting, hồi quy tuyến tính và cây quyết định.
  • rpart—cho phân hoạch đệ quy trong cây phân loại, hồi quy và sống sót.
  • glmnet—cho các phương pháp regularization lasso và elastic-net áp dụng cho hồi quy tuyến tính, logistic và đa thức.
  • nnet—cho mạng nơ-ron và thuật toán log-linear đa thức.
  • tensorflow—giao diện R cho TensorFlow, cho mạng nơ-ron sâu và tính toán số với đồ thị luồng dữ liệu.
  • Keras—giao diện R cho Keras, cho mạng nơ-ron sâu.

35. Cách chọn đặc trưng (feature) cho machine learning trong R?

Hãy xét ba cách tiếp cận và cách triển khai trong gói caret.

  1. Phát hiện và loại bỏ các đặc trưng tương quan cao khỏi tập dữ liệu.

Ta cần tạo ma trận tương quan của tất cả đặc trưng rồi xác định các đặc trưng tương quan cao, thường là những đặc trưng có hệ số tương quan lớn hơn 0.75:

corr_matrix <- cor(features)
highly_correlated <- findCorrelation(corr_matrix, cutoff=0.75)
print(highly_correlated)
  1. Xếp hạng các đặc trưng của data frame theo mức độ quan trọng.

Ta cần tạo sơ đồ huấn luyện để kiểm soát tham số cho train, dùng nó để xây dựng mô hình đã chọn, rồi ước lượng mức độ quan trọng biến cho mô hình đó:

control <- trainControl(method="repeatedcv", number=10, repeats=5)
model <- train(response_variable~., data=df, method="lvq", preProcess="scale", trControl=control)
importance <- varImp(model)
print(importance)
  1. Tự động chọn các đặc trưng tối ưu.

Một trong những phương pháp phổ biến do caret cung cấp để tự động chọn đặc trưng tối ưu là thuật toán chọn lùi gọi là Recursive Feature Elimination (RFE).

Ta cần tính phần điều khiển bằng phương pháp lấy mẫu lại đã chọn và danh sách hàm định sẵn, áp dụng thuật toán RFE bằng cách truyền vào các đặc trưng, biến mục tiêu, số đặc trưng giữ lại và phần điều khiển, rồi trích xuất các predictor đã chọn:

control <- rfeControl(functions=caretFuncs, method="cv", number=10)
results <- rfe(features, target_variable, sizes=c(1:8), rfeControl=control)
print(predictors(results))

Nếu bạn cần củng cố kỹ năng machine learning trong R, đây là tài nguyên vững chắc và toàn diện: Nhà khoa học Machine Learning với R.

36. Tương quan (correlation) và hiệp phương sai (covariance) là gì, và tính chúng trong R như thế nào?

Tương quan đo lường độ mạnh và hướng của mối quan hệ tuyến tính giữa hai biến. Nó nhận giá trị từ -1 (tương quan âm hoàn hảo) đến 1 (tương quan dương hoàn hảo). Hiệp phương sai đo lường mức độ hai biến thay đổi tương đối với nhau và hướng của mối quan hệ tuyến tính giữa chúng. Khác với tương quan, hiệp phương sai không bị giới hạn phạm vi giá trị.

Trong R, để tính tương quan, dùng hàm cor(); để tính hiệp phương sai—dùng cov(). Cú pháp hai hàm giống nhau: truyền vào hai biến (vector) muốn tính (ví dụ, cor(vector_1, vector_2) hoặc cov(vector_1, vector_2)), hoặc truyền cả data frame nếu muốn tính giữa tất cả biến của data frame đó (ví dụ, cor(df) or cov(df)). Với hai vector, kết quả là một giá trị đơn; với data frame, kết quả là ma trận tương quan (hoặc hiệp phương sai).

37. Liệt kê và định nghĩa các cách ước lượng độ chính xác mô hình trong R.

Dưới đây là vài cách tiếp cận và cách triển khai trong gói caret của R.

  • Chia tách dữ liệu—toàn bộ tập dữ liệu được chia thành tập huấn luyện và tập kiểm tra. Tập đầu dùng để fit mô hình, tập sau để kiểm tra hiệu suất trên dữ liệu chưa thấy. Cách này đặc biệt hiệu quả với dữ liệu lớn. Để triển khai trong R, dùng hàm createDataPartition() và đặt tham số p là tỷ lệ dữ liệu dùng huấn luyện.
  • Lấy mẫu bootstrap—lấy các mẫu ngẫu nhiên từ tập dữ liệu và ước lượng mô hình trên chúng. Các lần lấy mẫu này chạy nhiều lần và có hoàn lại. Để triển khai bootstrap trong R, đặt tham số method của hàm trainControl() thành "boot" khi định nghĩa điều khiển huấn luyện.
  • Các phương pháp cross-validation
    • k-fold cross-validation —tập dữ liệu chia thành k phần. Mô hình huấn luyện trên k-1 phần và kiểm tra trên phần còn lại. Quy trình lặp cho mọi phần, rồi ước lượng độ chính xác cuối cùng.
    • Repeated k-fold cross-validation —nguyên tắc giống k-fold, chỉ khác là tập dữ liệu được chia thành k phần nhiều hơn một lần. Với mỗi lần lặp, ước lượng độ chính xác, rồi tính trung bình qua tất cả lần lặp.
    • Leave-one-out cross-validation (LOOCV) —loại bỏ một quan sát ra ngoài và huấn luyện mô hình trên tất cả quan sát còn lại. Lặp cho mọi quan sát.

Để triển khai các phương pháp này trong R, đặt tham số method của trainControl() thành "cv", "repeatedcv" hoặc "LOOCV" tương ứng khi định nghĩa điều khiển huấn luyện.

38. Kiểm định chi-bình phương là gì và thực hiện trong R như thế nào?

Kiểm định giả thuyết chi-bình phương là kỹ thuật dùng để xác định liệu hai biến phân loại có độc lập hay có tương quan với nhau. Để thực hiện kiểm định chi-bình phương trong R, dùng hàm chisq.test() của gói stats. Các bước như sau:

1. Tạo bảng chéo với các biến phân loại quan tâm bằng hàm table() của base R:

table = table(df["var_1"], df["var_2"]) 

2. Truyền bảng chéo vào hàm chisq.test():

chisq.test(table) 

Bạn có thể ôn lại kiểm định chi-bình phương và các kiểm định giả thuyết khác trong khóa học Kiểm định Giả thuyết trong R.

39. Shiny trong R là gì?

Shiny là gói R mã nguồn mở cho phép xây dựng các ứng dụng web và trang web tương tác đầy đủ cho khoa học dữ liệu một cách dễ dàng và nhanh chóng chỉ với R, không cần biết HTML, CSS hoặc JavaScript. Shiny trong R cung cấp vô số tính năng cơ bản và nâng cao, widget, bố cục, ví dụ ứng dụng web và mã nền để kế thừa và tùy biến, cũng như các phần trình diễn từ người dùng trong nhiều lĩnh vực (công nghệ, thể thao, ngân hàng, giáo dục, v.v.) được cộng đồng nhà phát triển Shiny thu thập và phân loại.

40. Khác biệt giữa hàm with() và within()?

Hàm with() đánh giá một biểu thức R trên một hoặc nhiều biến của data frame và xuất ra kết quả mà không sửa đổi data frame. Hàm within() đánh giá một biểu thức R trên một hoặc nhiều biến của data frame, chỉnh sửa data frame, và xuất ra kết quả. Dưới đây là cách các hàm này hoạt động với một data frame mẫu:

df <- data.frame(a = c(1, 2, 3),  b = c(10, 20, 30))
print(df)

with(df, a * b)

print(within(df, c <- a * b))

Output:

  a  b
1 1 10
2 2 20
3 3 30

10  40  90
  a  b  c
1 1 10 10
2 2 20 40
3 3 30 90

Khi dùng within(), để lưu thay đổi, ta cần gán đầu ra của hàm cho một biến.

Kết luận

Tóm lại, trong bài viết này, chúng ta đã xem xét 40 câu hỏi phỏng vấn lập trình R phổ biến nhất và những câu trả lời kỳ vọng cho từng câu. Hy vọng với những thông tin này, bạn cảm thấy tự tin hơn và sẵn sàng cho một buổi phỏng vấn R thành công, dù bạn đang tìm việc với R hay tìm ứng viên phù hợp cho vị trí trống tại công ty.

Để có thêm trải nghiệm thực hành trả lời câu hỏi, hãy xem khóa học Luyện tập Câu hỏi Phỏng vấn Thống kê trong R.


Elena Kosourova's photo
Author
Elena Kosourova
LinkedIn

Nhà khoa học dữ liệu được chứng nhận bởi IBM (2020), trước đây là Nhà địa chất/Người xây dựng mô hình địa chất cho các mỏ dầu khí trên toàn thế giới với hơn 12 năm kinh nghiệm làm việc quốc tế. Thành thạo Python, R và SQL. Lĩnh vực chuyên môn: làm sạch dữ liệu, xử lý dữ liệu, trực quan hóa dữ liệu, phân tích dữ liệu, mô hình hóa dữ liệu, thống kê, kể chuyện bằng dữ liệu, học máy. Có nhiều kinh nghiệm trong quản lý cộng đồng khoa học dữ liệu và viết/biên tập bài viết, hướng dẫn về khoa học dữ liệu và định hướng nghề nghiệp.

Chủ đề
R
Dịch vụ Nghề nghiệp

Bắt đầu hành trình R của bạn ngay hôm nay!

Lộ trình

Nhà phát triển R

52 giờ
Nâng cao các kỹ năng phát triển sự nghiệp cần thiết để thành công trong vai trò Nhà phát triển R bằng cách học cách viết và đóng gói mã một cách hiệu quả. Không cần có kinh nghiệm lập trình!
Xem chi tiếtBắt Đầu Khóa Học

Tạo tài khoản miễn phí của bạn

Luyện tập và Lộ trình tiến trình của bạn.

Tiếp Tục Với Google
Bằng cách tiếp tục, bạn chấp nhận Điều khoản sử dụng, Chính sách bảo mật và việc dữ liệu của bạn được lưu trữ tại Hoa Kỳ.
Xem thêm
Liên quan

blog

Claude Opus 4.6: Tính năng, Điểm chuẩn, Bài kiểm tra thực hành và hơn thế nữa

Mô hình mới nhất của Anthropic dẫn đầu ở mã hóa tác tử và lập luận phức tạp. Thêm vào đó, nó có cửa sổ ngữ cảnh 1M.
Matt Crabtree's photo

Matt Crabtree

10 phút

Xem thêm