www.tuhocr.comBạn có folder này chứa 332 file .csv tương ứng 332 cảm
biến theo dõi chỉ tiêu sulfate và nitrate chất lượng nước ở các địa điểm
khác nhau (số liệu mô phỏng, không có thực). Nguồn dataset từ
Coursera/Data Science Specialization.
File .Rmd để render ở đây
https://tuhocr.netlify.app/code/project-coding-solution.Rmd
Download dataset https://tinyurl.com/4sm9ce76
sau đó giải nén ra folder specdata rồi đặt trong folder
project R.
Cấu trúc 1 file .csv như sau:
data_020 <- read.csv("specdata/020.csv")
dim(data_020)## [1] 1461 4
head(data_020)## Date sulfate nitrate ID
## 1 2002-01-01 NA NA 20
## 2 2002-01-02 NA NA 20
## 3 2002-01-03 NA NA 20
## 4 2002-01-04 NA NA 20
## 5 2002-01-05 NA NA 20
## 6 2002-01-06 NA NA 20
Ở dataset 020.csv có:
bao nhiêu dòng, bao nhiêu cột
bao nhiêu giá trị missing value ở cột
sulfate
bao nhiêu giá trị missing value ở cột
nitrate
bao nhiêu giá trị missing value ở cả 2 cột sulfate
và nitrate
có bao nhiêu ngày quan sát nào có ĐỦ CẢ 2 giá trị theo dõi
Tìm giá trị trung bình, max, min ở từng cột cho 2 trường hợp:
loại missing value riêng từng cột
loại missing value cho toàn bộ (tức là ở những cột có đủ 2 giá trị)
020.csv trước khi phân tích# Import dataset
data_020 <- read.csv("specdata/020.csv")
# Kiểm tra dataset
sapply(data_020, class)## Date sulfate nitrate ID
## "character" "numeric" "numeric" "integer"
str(data_020)## 'data.frame': 1461 obs. of 4 variables:
## $ Date : chr "2002-01-01" "2002-01-02" "2002-01-03" "2002-01-04" ...
## $ sulfate: num NA NA NA NA NA NA NA NA NA NA ...
## $ nitrate: num NA NA NA NA NA NA NA NA NA NA ...
## $ ID : int 20 20 20 20 20 20 20 20 20 20 ...
summary(data_020)## Date sulfate nitrate ID
## Length:1461 Min. : 0.472 Min. :0.1080 Min. :20
## Class :character 1st Qu.: 2.147 1st Qu.:0.3032 1st Qu.:20
## Mode :character Median : 3.180 Median :0.4740 Median :20
## Mean : 3.625 Mean :0.7780 Mean :20
## 3rd Qu.: 4.890 3rd Qu.:0.8140 3rd Qu.:20
## Max. :14.400 Max. :6.7700 Max. :20
## NA's :1337 NA's :1333
# Chuyển cột `Date` character thành `Date` chuẩn vector ngày tháng
data_020$Date <- as.Date(data_020$Date, format = "%Y-%m-%d")
sapply(data_020, class) # kiểm tra lại class dataset 020.csv## Date sulfate nitrate ID
## "Date" "numeric" "numeric" "integer"
dim(data_020)## [1] 1461 4
sulfate# Cách 1: Nhìn từ kết quả của lệnh `summary`
summary(data_020$sulfate)## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.472 2.147 3.180 3.625 4.890 14.400 1337
# Cách 2: Đếm trực tiếp NA dùng lệnh `sum(is.na(object))`
sum(is.na(data_020$sulfate))## [1] 1337
nitrate# Cách 1: Nhìn từ kết quả của lệnh `summary`
summary(data_020$nitrate)## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.1080 0.3032 0.4740 0.7780 0.8140 6.7700 1333
# Cách 2: Đếm trực tiếp NA dùng lệnh `sum(is.na(object))`
sum(is.na(data_020$nitrate))## [1] 1333
sulfate và
nitratelength(intersect(which(is.na(data_020$sulfate)), which(is.na(data_020$nitrate))))## [1] 1333
# Cách 1: Tiếp cận theo cách làm phép cộng giữa 2 vector để tách ra giá trị `NA`
length(data_020$sulfate + data_020$nitrate) - sum(is.na(data_020$sulfate + data_020$nitrate))## [1] 124
# Cách 2: Tiếp cận trực tiếp kiểm tra giá trị không phải là `NA` ở hai chỉ tiêu và CÓ GIAO NHAU
length(intersect(which(!is.na(data_020$nitrate)), which(!is.na(data_020$sulfate))))## [1] 124
i) loại missing value riêng từng cột
# Cách 1: Làm thủ công
## sulfate
mean(data_020$sulfate, na.rm = TRUE)## [1] 3.625065
max(data_020$sulfate, na.rm = TRUE)## [1] 14.4
min(data_020$sulfate, na.rm = TRUE)## [1] 0.472
## nitrate
mean(data_020$nitrate, na.rm = TRUE)## [1] 0.7780469
max(data_020$nitrate, na.rm = TRUE)## [1] 6.77
min(data_020$nitrate, na.rm = TRUE)## [1] 0.108
# Cách 2: Áp dụng lệnh sapply
## tạo danh sách function để loop
funs <- list(gia_tri_trung_binh = mean, cuc_dai = max, cuc_tieu = min)
## trả về matrix kết quả cho cả hai chỉ tiêu
##### cách 2a):
sapply(funs, function(x) sapply(data_020[, 2:3], x, na.rm = TRUE))## gia_tri_trung_binh cuc_dai cuc_tieu
## sulfate 3.6250645 14.40 0.472
## nitrate 0.7780469 6.77 0.108
##### cách 2b):
sapply(funs, mapply, data_020[, 2:3], na.rm = TRUE)## gia_tri_trung_binh cuc_dai cuc_tieu
## sulfate 3.6250645 14.40 0.472
## nitrate 0.7780469 6.77 0.108
ii) loại missing value cho toàn bộ (tức là ở những cột có đủ 2 giá trị)
sapply(funs, function(x) sapply(na.omit(data_020)[, 2:3], x))## gia_tri_trung_binh cuc_dai cuc_tieu
## sulfate 3.625065 14.40 0.472
## nitrate 0.791371 6.77 0.108
Trong dataset này có hai chỉ tiêu sulfate và
nitrate được cảm biến đo độc lập nhau. Có những ngày ghi
nhận được giá trị sulfate hoặc nitrate, có
những ngày không ghi nhận giá trị gì cả (missing value), cũng như có
ngày ghi nhận đầy đủ cả 2 giá trị sulfate và
nitrate.
Bạn hãy xây dựng function để tìm ra có bao nhiêu giá trị quan sát đầy đủ tương ứng ở từng cảm biến, để làm cơ sở đánh giá xem các cảm biến ở những vị trí khác nhau thì số lượng kết quả theo dõi có đồng đều nhau hay không.
# gọi function ra, đưa tham số là các dataset id cần tìm xem có bao nhiêu ngày có đầy đủ giá trị quan sát
# > complete("specdata", id = 18:22)
# id full_quan_sat
# 1 18 84
# 2 19 353
# 3 20 124 ← đây chính là kết quả câu 1e) khi tính thủ công
# 4 21 426
# 5 22 135Cách 1: Function complete_1 tìm full
giá trị quan sát, xây dựng theo cách tiếp cận for
loop và gom lại thành data frame master, sau đó subset ra, tìm
giá trị full_quan_sat bằng phép toán giữa các chỉ tiêu với
NA (tương tự cách 1 ở câu 1e)
complete_1 <- function(directory = "specdata", id){
files_list <- list.files(directory, full.names = TRUE)
tmp <- files_list[id] # Đây là chỗ tùy chọn
tmp_working <- vector(mode = "list", length = length(tmp))
for (i in seq_along(tmp)) {
tmp_working[[i]] <- read.csv(tmp[[i]]) # Kiểu subset của tmp_working là dạng list tách ra dạng bảng
}
output_tmp_working <- do.call(rbind, tmp_working)
y <- unique(output_tmp_working$ID) # Đếm số lần xuất hiện (number of occurences for each unique value)
extract_data <- data.frame(matrix(ncol = 2, nrow = 0))
for (uu in seq_along(y)) {
happy <- output_tmp_working[which(output_tmp_working[, "ID"] == y[uu]),]
sul <- happy[,2]
nit <- happy[,3]
tot <- sul + nit
sum(is.na(tot)) #Hàm đếm missing values trong vector
nobs <- length(tot) - sum(is.na(tot))
extract_data <- rbind(extract_data, c(y[uu], nobs))
}
x <- c("cam_bien", "full_quan_sat")
colnames(extract_data) <- x
return(extract_data)
}Test function complete_1
complete_1("specdata", id = 10:20)## cam_bien full_quan_sat
## 1 10 148
## 2 11 443
## 3 12 96
## 4 13 46
## 5 14 96
## 6 15 83
## 7 16 60
## 8 17 927
## 9 18 84
## 10 19 353
## 11 20 124
Cách 2: Function complete_2 tìm full
giá trị quan sát, xây dựng theo cách tiếp cận sử dụng hàm
apply, không gom lại thành data frame master mà chỉ dừng ở
list master, khi cần subset thì gọi ra theo id, tìm
giá trị full_quan_sat theo kiểu trực tiếp (tương tự cách 2
ở câu 1e)
complete_2 <- function(directory = "specdata", id){
# import dataset
files_list <- list.files(directory, full.names = TRUE,
pattern = ".csv") # set này để chọn riêng file .csv
tmp_working <- lapply(files_list[id], read.csv)
# FUNCTION
check_full_quan_sat <- function(check_id){
raw <- tmp_working[[check_id]]
check_1 <- which(!is.na(raw$nitrate))
check_2 <- which(!is.na(raw$sulfate))
ra_soat <- intersect(check_1, check_2)
length(ra_soat)
}
# sửa lại chỗ sapply seq_along(tmp_working)
full_quan_sat <- sapply(seq_along(tmp_working), check_full_quan_sat)
full_quan_sat <- as.data.frame(full_quan_sat)
ket_qua <- cbind(cam_bien = id, full_quan_sat)
return(ket_qua)
}Test function complete_2
complete_2("specdata", id = 10:20)## cam_bien full_quan_sat
## 1 10 148
## 2 11 443
## 3 12 96
## 4 13 46
## 5 14 96
## 6 15 83
## 7 16 60
## 8 17 927
## 9 18 84
## 10 19 353
## 11 20 124
Kết quả từ cả hai function này trả về là y chang nhau.
identical(complete_1("specdata", id = 1:332),
complete_2("specdata", id = 1:332))## [1] TRUE
Xem thêm so sánh tốc độ hai
function:
https://www.tuhocr.com/blog/danh-gia-toc-do-function
Xây dựng function trả về kết quả mean ở từng chỉ tiêu
theo giá trị id của mỗi dataset.
pollutantmean <- function(directory = "specdata", pollutant, id = 1:332) {
# import dataset
files_list <- list.files(directory, full.names = TRUE,
pattern = ".csv") # set này để chọn riêng file .csv
tmp_working <- lapply(files_list[id], read.csv)
# gom chung 1 dataset
output_tmp_working <- do.call(rbind, tmp_working)
mean(output_tmp_working[, pollutant], na.rm = TRUE)
}Test function pollutantmean
pollutantmean("specdata", "nitrate", 3:10)## [1] 0.7471877
pollutantmean("specdata", "nitrate", 20)## [1] 0.7780469
pollutantmean("specdata", "sulfate", 1:332)## [1] 3.189369
pollutantmean("specdata", "sulfate", c(1:20, 50:110))## [1] 3.484405
Liệt kê giá trị max và min ở cả 2 chỉ tiêu
ở các dãy cảm biến bất kỳ.
Đầu tiên, ta tận dụng lại hàm
filter_theo_chi_tieu_super, đã xây dựng trước
đây
https://www.tuhocr.com/huong-dan-cai-tien-function-step-by-step
Có hai cải tiến khi kế thừa function đã có và áp dụng trong bài này:
Khi áp dụng vào trong dataset này, thì
cần lưu ý chỗ cột Date ở dataset 001.csv nó
theo cấu trúc MM/DD/YYYY khác biệt so với cấu trúc
YYYY-MM-DD ở các dataset còn lại. Do đó khi import vảo, chỗ
convert qua date-vector thì cần có hàm if-else
để nhận biết chuyện này để convert cho đủ cả các trường hợp có format
ban đầu Date khác nhau.
Chỉ tiêu nitrate có một số
dataset hoàn toàn không có bất kỳ giá trị nào, vì vậy khi tìm
min hay max sẽ xuất hiện warning
message mặc dù vẫn trả ra kết quả cho những dataset còn lại. Để
thuận tiện thì ta dùng lệnh suppressWarnings() để tắt các
thông báo này.
library(dplyr)
## FUNCTION_MIN_CHI_TIEU
"%min_chi_tieu%" <- function(a, b){
# import dataset
files_list <- list.files(b, full.names = TRUE)
tmp_working <- vector(mode = "list", length = length(files_list))
for(i in seq_along(files_list)) {
tmp_working[[i]] <- read.csv(files_list[i])
tmp_working[[i]]$Date <- as.Date(tmp_working[[i]]$Date, format = "%Y-%m-%d")
if(any(is.na(tmp_working[[i]]$Date))){
tmp_working[[i]] <- read.csv(files_list[i])
tmp_working[[i]]$Date <- as.Date(tmp_working[[i]]$Date, format = "%m/%d/%Y")
}
}
# find min value
ket_qua_min <- data.frame()
for(min_i in seq_along(tmp_working)) {
if(chi_tieu %in% names(tmp_working[[min_i]])){
gia_tri_min <- suppressWarnings(min(get(chi_tieu, tmp_working[[min_i]]), na.rm = TRUE))
### trích xuất ra vị trí index
vi_tri <- which(get(chi_tieu, tmp_working[[min_i]]) == gia_tri_min)
ket_qua_min <- bind_rows(ket_qua_min, tmp_working[[min_i]][vi_tri, ])
}
next
}
#### THÊM DÒNG THÔNG BÁO
print(paste("Kết quả lọc theo giá trị MIN của", chi_tieu, "ở folder", b, "là:"))
#### TRẢ KẾT QUẢ
return(ket_qua_min)
}
## FUNCTION_MAX_CHI_TIEU
"%max_chi_tieu%" <- function(a, b){
# import dataset
files_list <- list.files(b, full.names = TRUE)
tmp_working <- vector(mode = "list", length = length(files_list))
for(i in seq_along(files_list)) {
tmp_working[[i]] <- read.csv(files_list[i])
tmp_working[[i]]$Date <- as.Date(tmp_working[[i]]$Date, format = "%Y-%m-%d")
if(any(is.na(tmp_working[[i]]$Date))){
tmp_working[[i]] <- read.csv(files_list[i])
tmp_working[[i]]$Date <- as.Date(tmp_working[[i]]$Date, format = "%m/%d/%Y")
}
}
# find max value
ket_qua_max <- data.frame()
for(max_i in seq_along(tmp_working)) {
if(chi_tieu %in% names(tmp_working[[max_i]])){
gia_tri_max <- suppressWarnings(max(get(chi_tieu, tmp_working[[max_i]]), na.rm = TRUE))
### trích xuất ra vị trí index
vi_tri <- which(get(chi_tieu, tmp_working[[max_i]]) == gia_tri_max)
ket_qua_max <- bind_rows(ket_qua_max, tmp_working[[max_i]][vi_tri, ])
}
next
}
#### THÊM DÒNG THÔNG BÁO
print(paste("Kết quả lọc theo giá trị MAX của", chi_tieu, "ở folder", b, "là:"))
#### TRẢ KẾT QUẢ
return(ket_qua_max)
}
### FUNCTION RANGE CHỈ TIÊU
"%range_chi_tieu%" <- function(a, b){
# import dataset
files_list <- list.files(b, full.names = TRUE)
tmp_working <- vector(mode = "list", length = length(files_list))
for(i in seq_along(files_list)){
tmp_working[[i]] <- read.csv(files_list[i])
tmp_working[[i]]$Date <- as.Date(tmp_working[[i]]$Date, format = "%Y-%m-%d")
if(any(is.na(tmp_working[[i]]$Date))){
tmp_working[[i]] <- read.csv(files_list[i])
tmp_working[[i]]$Date <- as.Date(tmp_working[[i]]$Date, format = "%m/%d/%Y")
}
}
# tìm trong khoảng
ket_qua_range <- data.frame()
for(range_i in seq_along(tmp_working)){
if(chi_tieu %in% names(tmp_working[[range_i]])) {
ket_qua_tim_trong_khoang <- which(get(chi_tieu, tmp_working[[range_i]]) >= a[1] &
get(chi_tieu, tmp_working[[range_i]]) <= a[2])
ket_qua_range <- bind_rows(ket_qua_range, tmp_working[[range_i]][ket_qua_tim_trong_khoang, ])
}
next
}
print(paste("Kết quả lọc trong khoảng, từ", a[1], "đến", a[2], "của", chi_tieu, "ở folder", b, "là:"))
return(ket_qua_range )
}
### function chung
"%chi_tieu%" <- function(a, b){
if(length(a) == 1){
switch(a,
"min" = a %min_chi_tieu% b,
"max" = a %max_chi_tieu% b)
} else {
a %range_chi_tieu% b
}
}
### FUNCTION FINAL
filter_theo_chi_tieu_enhanced <- function(chi_tieu = "mercury", a = "min", b = "2007"){
chi_tieu <<- chi_tieu ### sử dụng super assign
a %chi_tieu% b
}
##################
filter_theo_chi_tieu_super <- function(chi_tieu = "mercury", a = "min", b = "2007") {
data_1 <- filter_theo_chi_tieu_enhanced(chi_tieu, a, b)
if(length(data_1) != 0) {
kq_sort <- sort(names(data_1)[!(names(data_1) %in% c("Date", "ID"))])
ok <- c("Date", kq_sort, "ID")
data_2 <- data_1[ok]
return(data_2)
}
return("Không có kết quả tìm kiếm")
}Để thêm chức năng tìm theo
id thì thay vì ta đưa câu lệnh vào trong hàm
filter_theo_chi_tieu_super thì sẽ gây cồng kềnh. Ta sẽ làm
1 hàm mới là filter_theo_id, rồi nested hàm
filter_theo_chi_tieu_super vào thì sẽ tiện hơn.
filter_theo_id <- function(chi_tieu = "sulfate", a = "max", b = "specdata", id_can_tim) {
data_filter <- filter_theo_chi_tieu_super(chi_tieu, a, b)
vi_tri <- which(get("ID", data_filter) %in% id_can_tim)
ket_qua_chuan <- data_filter[vi_tri, ]
return(ket_qua_chuan)
}Test hàm
filter_theo_id
filter_theo_id(chi_tieu = "sulfate", a = "max", b = "specdata", id = 280:332)## [1] "Kết quả lọc theo giá trị MAX của sulfate ở folder specdata là:"
## Date nitrate sulfate ID
## 285 2005-09-07 NA 6.33593 280
## 286 2000-10-21 0.256 18.00000 281
## 287 2000-10-24 0.687 15.20000 282
## 288 2000-10-24 0.849 16.30000 283
## 289 2002-09-14 NA 27.20000 284
## 290 2000-10-24 0.414 18.40000 285
## 291 2002-08-30 NA 14.80000 286
## 292 2000-10-24 0.899 16.30000 287
## 293 2002-08-29 NA 19.00000 288
## 294 2002-09-11 NA 19.00000 288
## 295 2005-08-02 NA 5.71843 289
## 296 2002-09-14 NA 24.80000 290
## 297 2002-08-30 NA 18.00000 291
## 298 2005-06-21 NA 10.23036 292
## 299 2005-04-16 NA 5.58111 293
## 300 2005-06-27 NA 12.27128 294
## 301 2000-10-21 0.688 12.40000 295
## 302 2002-08-30 NA 13.90000 296
## 303 2002-09-14 NA 19.20000 297
## 304 2002-12-10 15.100 8.69000 298
## 305 2004-01-22 16.400 4.71000 299
## 306 2001-01-04 18.700 14.60000 300
## 307 2004-01-16 31.300 5.79000 301
## 308 2001-07-24 0.284 18.80000 302
## 309 2007-08-07 0.257 20.50000 303
## 310 2006-08-03 0.567 14.50000 304
## 311 2003-06-26 1.340 22.80000 305
## 312 2001-08-08 0.251 24.70000 306
## 313 2002-07-01 1.400 23.80000 307
## 314 2009-08-23 0.340 2.35000 308
## 315 2004-11-05 3.240 3.50000 309
## 316 2002-10-23 3.230 3.89000 310
## 317 2001-08-17 0.619 3.22000 311
## 318 2004-12-17 2.740 5.30000 312
## 319 2004-12-17 2.800 5.18000 313
## 320 2004-10-03 3.470 4.95000 314
## 321 2006-07-04 0.748 3.67000 315
## 322 2009-01-19 1.920 3.52000 316
## 323 2009-08-17 0.760 2.20000 317
## 324 2007-11-20 1.870 2.44000 318
## 325 2007-11-23 3.180 2.61000 319
## 326 2007-08-04 0.226 20.70000 320
## 327 2007-08-04 0.618 19.20000 321
## 328 2005-06-27 0.330 25.50000 322
## 329 2010-01-14 2.390 5.56000 323
## 330 2010-03-09 9.000 5.21000 324
## 331 2005-06-27 1.850 22.20000 325
## 332 2005-08-02 1.280 22.80000 326
## 333 2002-09-29 3.950 12.20000 327
## 334 2005-08-02 1.010 23.90000 328
## 335 2005-08-02 0.698 12.60000 329
## 336 2005-06-27 1.470 20.50000 330
## 337 2002-08-03 0.249 10.20000 331
## 338 2004-04-09 0.150 2.94000 332
filter_theo_id(chi_tieu = "nitrate", a = "min", b = "specdata", id = 280:332)## [1] "Kết quả lọc theo giá trị MIN của nitrate ở folder specdata là:"
## Date nitrate sulfate ID
## 284 2001-03-08 0.1480 1.9600 280
## 285 2000-08-29 0.0215 0.1540 281
## 286 2001-02-03 0.0751 0.3900 282
## 287 2000-09-14 0.0985 3.0500 283
## 288 2001-01-31 0.0867 0.2740 284
## 289 2000-11-02 0.1450 11.5000 285
## 290 2010-03-06 0.0516 0.0710 287
## 291 2010-01-26 0.0959 0.5300 288
## 292 2000-09-01 0.0228 0.0966 290
## 293 2000-09-26 0.0255 0.0774 295
## 294 2001-01-31 0.3050 1.6600 296
## 295 2001-04-25 0.2340 1.7600 297
## 296 2002-09-29 0.1090 0.5340 298
## 297 2008-08-16 0.0506 0.6130 299
## 298 2008-11-02 0.0447 0.0000 300
## 299 2005-11-06 0.0846 0.2790 301
## 300 2001-03-02 0.0000 0.1740 302
## 301 2007-05-12 0.0000 0.0473 302
## 302 2008-07-08 0.0000 0.0000 302
## 303 2009-04-07 0.0860 1.6600 303
## 304 2004-09-18 0.0779 0.7370 304
## 305 2005-06-03 0.0519 0.0341 305
## 306 2003-01-09 0.0601 NA 306
## 307 2003-12-11 0.1160 1.4100 307
## 308 2010-04-02 0.1340 0.3230 308
## 309 2002-07-19 0.1660 1.2300 309
## 310 2000-05-27 0.1308 0.3681 310
## 311 2002-12-10 0.2570 NA 311
## 312 2003-10-30 0.2020 0.6720 312
## 313 2009-07-06 0.0922 0.9490 313
## 314 2008-11-08 0.1110 0.2900 314
## 315 2006-03-06 0.0885 0.2600 315
## 316 2010-04-02 0.1030 NA 316
## 317 2010-04-02 0.0963 0.3670 317
## 318 2008-08-10 0.0550 0.7060 318
## 319 2008-04-30 0.0903 0.3470 319
## 320 2009-10-28 0.0719 2.0900 320
## 321 2009-06-30 0.1600 3.5600 321
## 322 2008-09-15 0.0979 1.2100 322
## 323 2009-10-10 0.1590 1.1100 323
## 324 2010-04-08 0.1600 0.4810 324
## 325 2009-07-12 0.0711 0.5270 325
## 326 2005-05-16 0.0768 0.6730 326
## 327 2004-07-02 0.1850 0.3640 327
## 328 2009-09-28 0.0653 0.5500 328
## 329 2009-07-06 0.0284 NA 329
## 330 2009-09-28 0.0828 0.5250 330
## 331 2005-12-27 0.1000 0.3280 331
## 332 2004-02-03 0.1250 0.4680 332
filter_theo_id(chi_tieu = "nitrate", a = c(0.667, 0.700), b = "specdata", id = c(12:14, 20:22))## [1] "Kết quả lọc trong khoảng, từ 0.667 đến 0.7 của nitrate ở folder specdata là:"
## Date nitrate sulfate ID
## 99 2004-05-27 0.692 1.34 12
## 100 2003-05-21 0.676 1.92 13
## 122 2002-11-10 0.680 3.48 20
## 123 2002-04-08 0.698 1.73 21
## 124 2003-03-28 0.694 1.67 21
## 125 2003-09-12 0.686 5.72 21
## 126 2003-10-30 0.669 3.01 21
## 127 2004-05-09 0.689 6.80 21
## 128 2005-04-16 0.675 6.21 21
## 129 2005-05-22 0.676 7.30 21
## 130 2007-05-24 0.667 4.40 21
## 131 2007-10-15 0.681 2.48 21
## 132 2008-06-11 0.680 2.53 21
## 133 2008-07-11 0.674 2.27 21
## 134 2009-12-27 0.674 1.21 21
## 135 2002-04-20 0.667 3.29 22
## 136 2002-05-02 0.688 3.02 22
## 137 2004-09-30 0.688 1.66 22
## 138 2004-12-29 0.690 4.75 22
## 139 2005-02-21 0.669 2.95 22
## 140 2005-04-16 0.681 6.29 22
Thực tế ở thời điểm này chúng ta có thể dùng lệnh
merge() để ghép chung các dataset từ kết qua filter theo
từng chỉ tiêu, tuy nhiên như vậy cũng còn hơi thủ công, do đó ta sẽ đưa
lệnh merge() vào trong function mới là
filter_theo_id_so_sanh để kết quả trả về sẽ đúng format
mong muốn.
filter_theo_id_so_sanh <- function(chi_tieu_1,
chi_tieu_2,
a, b, id_can_tim) {
ok_1 <- filter_theo_id(chi_tieu = chi_tieu_1, a, b, id_can_tim)
ok_2 <- filter_theo_id(chi_tieu = chi_tieu_2, a, b, id_can_tim)
if(length(a) == 1) {
ok_1$note <- paste(a[1], chi_tieu_1)
ok_2$note <- paste(a[1], chi_tieu_2)
} else {
ok_1$note <- paste("from", a[1], "to", a[2], chi_tieu_1)
ok_2$note <- paste("from", a[1], "to", a[2], chi_tieu_2)
}
ok_1$sep <- "|"
ket_qua_so_sanh <- merge(ok_1, ok_2, by = "ID", all = TRUE)
return(ket_qua_so_sanh)
}Test hàm
filter_theo_id_so_sanh
options(digits = 2)
options(width = 200)
filter_theo_id_so_sanh(chi_tieu_1 = "sulfate", chi_tieu_2 = "nitrate", a = "max", b = "specdata", id_can_tim = 280:300)## [1] "Kết quả lọc theo giá trị MAX của sulfate ở folder specdata là:"
## [1] "Kết quả lọc theo giá trị MAX của nitrate ở folder specdata là:"
## ID Date.x nitrate.x sulfate.x note.x sep Date.y nitrate.y sulfate.y note.y
## 1 280 2005-09-07 NA 6.3 max sulfate | 2001-01-01 9.76 2.6 max nitrate
## 2 281 2000-10-21 0.26 18.0 max sulfate | 2000-11-20 2.05 2.1 max nitrate
## 3 282 2000-10-24 0.69 15.2 max sulfate | 2001-02-04 3.81 2.4 max nitrate
## 4 283 2000-10-24 0.85 16.3 max sulfate | 2001-02-03 2.97 3.6 max nitrate
## 5 284 2002-09-14 NA 27.2 max sulfate | 2001-01-22 4.58 3.1 max nitrate
## 6 285 2000-10-24 0.41 18.4 max sulfate | 2000-12-05 2.65 4.2 max nitrate
## 7 286 2002-08-30 NA 14.8 max sulfate | <NA> NA NA <NA>
## 8 287 2000-10-24 0.90 16.3 max sulfate | 2001-01-04 5.59 3.8 max nitrate
## 9 288 2002-08-29 NA 19.0 max sulfate | 2009-12-09 2.08 2.1 max nitrate
## 10 288 2002-09-11 NA 19.0 max sulfate | 2009-12-09 2.08 2.1 max nitrate
## 11 289 2005-08-02 NA 5.7 max sulfate | <NA> NA NA <NA>
## 12 290 2002-09-14 NA 24.8 max sulfate | 2001-01-25 2.05 5.5 max nitrate
## 13 291 2002-08-30 NA 18.0 max sulfate | <NA> NA NA <NA>
## 14 292 2005-06-21 NA 10.2 max sulfate | <NA> NA NA <NA>
## 15 293 2005-04-16 NA 5.6 max sulfate | <NA> NA NA <NA>
## 16 294 2005-06-27 NA 12.3 max sulfate | <NA> NA NA <NA>
## 17 295 2000-10-21 0.69 12.4 max sulfate | 2000-12-05 1.54 2.9 max nitrate
## 18 296 2002-08-30 NA 13.9 max sulfate | 2001-02-12 2.62 5.3 max nitrate
## 19 297 2002-09-14 NA 19.2 max sulfate | 2001-05-01 0.57 5.3 max nitrate
## 20 298 2002-12-10 15.10 8.7 max sulfate | 2002-02-07 38.20 6.2 max nitrate
## 21 299 2004-01-22 16.40 4.7 max sulfate | 2004-02-15 37.50 4.4 max nitrate
## 22 300 2001-01-04 18.70 14.6 max sulfate | 2002-02-07 41.60 6.5 max nitrate