Exercise 1: Mean of Positive Values

Bạn có thể mô phỏng các giá trị từ phân phối chuẩn bằng cách sử dụng hàm rnorm(). Đối số đầu tiên của hàm này là số lượng mẫu bạn muốn sinh ra. Nếu bạn không chỉ định thêm tham số nào khác, hàm sẽ lấy mẫu từ phân phối chuẩn N(0, 1).

Yêu cầu: Hãy viết một pipeline nhận đầu vào là các mẫu sinh ra từ hàm này, loại bỏ các giá trị âm, và tính giá trị trung bình của các giá trị còn lại.

Gợi ý: Một cách để loại bỏ các giá trị là thay thế các giá trị âm bằng giá trị thiếu (NA). Nếu một vector có chứa các giá trị NA, hàm mean() có thể bỏ qua các giá trị này nếu bạn truyền thêm tùy chọn na.rm = TRUE.


Cách 1: Không dùng pipeline

1. Sinh dữ liệu vector số ngẫu nhiên

set.seed(69) # Lock kết quả random
nums_vector <- rnorm(1000)

head(nums_vector) # Xem vài phần tử đầu
## [1]  0.07716537  0.37431557 -0.33481390 -0.94988897 -0.94021008  1.18962312
summary(nums_vector) # Chịu chết :v
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
## -3.06127 -0.68612 -0.07519 -0.02658  0.64971  3.14500
length(nums_vector) # Xem số phần tử
## [1] 1000

2. Xử lý số âm

a. Dùng ifelse()
so_duong_ifelse <- ifelse(nums_vector < 0, NA, nums_vector) # Lọc số âm

head(so_duong_ifelse) # Xem kết quả sau lọc
## [1] 0.07716537 0.37431557         NA         NA         NA 1.18962312
summary(so_duong_ifelse) # Thống kê sau lọc
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##  0.0039  0.3274  0.6858  0.7990  1.1751  3.1450     525
sum(is.na(so_duong_ifelse)) # Đếm số giá trị bị loại
## [1] 525
c. Dùng logical indexing
so_duong_peak <- nums_vector
so_duong_peak[so_duong_peak < 0] <- NA # Lọc số âm

head(so_duong_peak) # Xem kết quả sau lọc
## [1] 0.07716537 0.37431557         NA         NA         NA 1.18962312
summary(so_duong_peak) # Thống kê sau lọc
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##  0.0039  0.3274  0.6858  0.7990  1.1751  3.1450     525
sum(is.na(so_duong_peak)) # Đếm số giá trị bị loại
## [1] 525

3. Tính trung bình cộng các giá trị dương

trung_binh_cong_ifelse <- mean(so_duong_ifelse, na.rm = TRUE)
trung_binh_cong_peak <- mean(so_duong_peak, na.rm = TRUE)

4. In kết quả

cat("Trung bình cộng dùng ifelse:", trung_binh_cong_ifelse, "\n")
## Trung bình cộng dùng ifelse: 0.7989931
cat("Trung bình cộng dùng cách đỉnh cao:", trung_binh_cong_peak, "\n")
## Trung bình cộng dùng cách đỉnh cao: 0.7989931

Cách 2: Dùng pipeline

set.seed(69)

# Anonymous function: Giống Arrow function trong JavaScript :v
mean_pipeline <- rnorm(1000) |> (\(vector_nhan_vao) ifelse(vector_nhan_vao < 0, NA, vector_nhan_vao))() |> mean(na.rm = TRUE)
mean_pipeline
## [1] 0.7989931