Bạn sẽ nhận ra những giây phút nào là quan trọng nhất trong cuộc đời khi mà mọi chuyện đã muộn
library(tidyverse)
## ── Attaching packages ────────────────────────────────────────────────────── tidyverse 1.2.1 ──
## ✔ ggplot2 3.1.1 ✔ purrr 0.3.2
## ✔ tibble 2.1.1 ✔ dplyr 0.8.0.1
## ✔ tidyr 0.8.3 ✔ stringr 1.4.0
## ✔ readr 1.3.1 ✔ forcats 0.4.0
## ── Conflicts ───────────────────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
library(broom)
Giới thiệu
Hầu hết mọi người sử dụng package purrr thường chủ yếu tập trung vào các tính năng của hàm map_* mà quên đi nhiều tiện ích của purrr
Tận dụng các tiện ích của package purrr làm cho công việc viết code đơn giản như việc thưởng thức tách cafe, và hơn nữa code cũng sáng sủa, rõ ràng hơn
Thi thoảng thay đổi cách viết code cùng làm cho công việc bớt nhàm chán hơn
Trong phần này tôi sẽ giới thiệu 2 hàm compose và partial
compose()
Đầu tiên tôi ví dụ 1 đoạn code:
lm(Sepal.Length ~ Species, data = iris) %>% tidy() %>% filter(p.value < 0.05)
lm(Pepal.Length ~ Species, data = iris) %>% tidy() %>% filter(p.value < 0.05)
lm(Sepal.Width ~ Species, data = iris) %>% tidy() %>% filter(p.value < 0.05)
lm(Sepal.Length ~ Species, data = iris) %>% tidy() %>% ilter(p.value < 0.05)
Nếu chúng ta viết code như trên thông thường mắt của chúng ta sẽ chỉ tập trung vào những điểm giống nhau thay vì tập trung vào những điểm thay đổi của các dòng code. Vì vậy, coder rất dễ mắc lỗi khi viết nhiều dòng tương tự nhau. Chú ý rằng nếu code lặp lại trên 2 lần thì nên sử dụng function. Với purrr thay vì viết hàm mới thì chúng ta nên modify hoặc kết hợp các hàm lại với nhau
So sánh 2 cách viết
tidy(lm(Sepal.Length ~ Species, data = iris))
## # A tibble: 3 x 5
## term estimate std.error statistic p.value
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 (Intercept) 5.01 0.0728 68.8 1.13e-113
## 2 Speciesversicolor 0.93 0.103 9.03 8.77e- 16
## 3 Speciesvirginica 1.58 0.103 15.4 2.21e- 32
và cách 2 sử dụng hàm compose
tidy_lm <- compose(tidy, lm)
tidy_lm(Sepal.Length ~ Species, data = iris)
## # A tibble: 3 x 5
## term estimate std.error statistic p.value
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 (Intercept) 5.01 0.0728 68.8 1.13e-113
## 2 Speciesversicolor 0.93 0.103 9.03 8.77e- 16
## 3 Speciesvirginica 1.58 0.103 15.4 2.21e- 32
Như vậy, bằng cách kết hợp hàm lm và tidy (theo nguyên tắc từ phải sang trái) chúng ta có hàm tidy_lm ngắn gọn
Sử dụng as_mapper để convert 1 object sang function và cũng sử dụng hàm compose
clean_lm <- compose(as_mapper(~ arrange(.x, desc(p.value))),
as_mapper(~ filter(.x, p.value < 0.05)),
tidy,
lm)
clean_lm(Sepal.Length ~ Sepal.Width, data = iris)
## # A tibble: 1 x 5
## term estimate std.error statistic p.value
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 (Intercept) 6.53 0.479 13.6 6.47e-28
partial()
Cách viết thông thường khi tính giá trị trung bình với vector có giá trị NA
mean(airquality$Ozone, na.rm = TRUE)
## [1] 42.12931
Sử dụng hàm partial
mean_na_rm <- partial(mean, na.rm = TRUE)
mean_na_rm(airquality$Ozone)
## [1] 42.12931
kết quả tương tự đoạn code trên nhưng ngắn gọn hơn
Tham khảo: https://colinfay.me
LS0tCnRpdGxlOiAiSMaw4bubbmcgZOG6q24gc+G7rSBk4bulbmcgcHVycnIgcGFja2FnZSAocGFydCAyKSIKYXV0aG9yOiAiTmd1eeG7hW4gTmfhu41jIELDrG5oIgpkYXRlOiAiNSBBcHIgMjAxOSIKb3V0cHV0OgogICBodG1sX2RvY3VtZW50OiAKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgICNjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICB0aGVtZTogImRlZmF1bHQiCiAgICB0b2M6IFRSVUUKICAgIHRvY19mbG9hdDogVFJVRQogICAgZGV2OiAnc3ZnJwotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCgpgYGAKCj4gQuG6oW4gc+G6vSBuaOG6rW4gcmEgbmjhu69uZyBnacOieSBwaMO6dCBuw6BvIGzDoCBxdWFuIHRy4buNbmcgbmjhuqV0IHRyb25nIGN14buZYyDEkeG7nWkga2hpIG3DoCBt4buNaSBjaHV54buHbiDEkcOjIG114buZbgoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGJyb29tKQpgYGAKCgojIEdp4bubaSB0aGnhu4d1CgpI4bqndSBo4bq/dCBt4buNaSBuZ8aw4budaSBz4butIGThu6VuZyBwYWNrYWdlICoqcHVycnIqKiB0aMaw4budbmcgY2jhu6cgeeG6v3UgdOG6rXAgdHJ1bmcgdsOgbyBjw6FjIHTDrW5oIG7Eg25nIGPhu6dhIGjDoG0gbWFwXyogbcOgIHF1w6puIMSRaSBuaGnhu4F1IHRp4buHbiDDrWNoIGPhu6dhIHB1cnJyCgpU4bqtbiBk4bulbmcgY8OhYyB0aeG7h24gw61jaCBj4bunYSBwYWNrYWdlIHB1cnJyIGzDoG0gY2hvIGPDtG5nIHZp4buHYyB2aeG6v3QgY29kZSDEkcahbiBnaeG6o24gbmjGsCB2aeG7h2MgdGjGsOG7n25nIHRo4bupYyB0w6FjaCBjYWZlLCB2w6AgaMahbiBu4buvYSBjb2RlIGPFqW5nIHPDoW5nIHPhu6dhLCByw7UgcsOgbmcgaMahbgoKVGhpIHRob+G6o25nIHRoYXkgxJHhu5VpIGPDoWNoIHZp4bq/dCBjb2RlIGPDuW5nIGzDoG0gY2hvIGPDtG5nIHZp4buHYyBi4bubdCBuaMOgbSBjaMOhbiBoxqFuCgpUcm9uZyBwaOG6p24gbsOgeSB0w7RpIHPhur0gZ2nhu5tpIHRoaeG7h3UgMiBow6BtIGNvbXBvc2UgdsOgIHBhcnRpYWwgCgojIGNvbXBvc2UoKSAKCsSQ4bqndSB0acOqbiB0w7RpIHbDrSBk4bulIDEgxJFv4bqhbiBjb2RlOiAKCmBgYHtyLCBldmFsID0gRkFMU0V9CmxtKFNlcGFsLkxlbmd0aCB+IFNwZWNpZXMsIGRhdGEgPSBpcmlzKSAlPiUgdGlkeSgpICU+JSBmaWx0ZXIocC52YWx1ZSA8IDAuMDUpCmxtKFBlcGFsLkxlbmd0aCB+IFNwZWNpZXMsIGRhdGEgPSBpcmlzKSAlPiUgdGlkeSgpICU+JSBmaWx0ZXIocC52YWx1ZSA8IDAuMDUpCmxtKFNlcGFsLldpZHRoIH4gU3BlY2llcywgZGF0YSA9IGlyaXMpICU+JSB0aWR5KCkgJT4lIGZpbHRlcihwLnZhbHVlIDwgMC4wNSkKbG0oU2VwYWwuTGVuZ3RoIH4gU3BlY2llcywgZGF0YSA9IGlyaXMpICU+JSB0aWR5KCkgJT4lIGlsdGVyKHAudmFsdWUgPCAwLjA1KQoKYGBgCgpO4bq/dSBjaMO6bmcgdGEgdmnhur90IGNvZGUgbmjGsCB0csOqbiB0aMO0bmcgdGjGsOG7nW5nIG3huq90IGPhu6dhIGNow7puZyB0YSBz4bq9IGNo4buJIHThuq1wIHRydW5nIHbDoG8gbmjhu69uZyDEkWnhu4NtIGdp4buRbmcgbmhhdSB0aGF5IHbDrCB04bqtcCB0cnVuZyB2w6BvIG5o4buvbmcgxJFp4buDbSB0aGF5IMSR4buVaSBj4bunYSBjw6FjIGTDsm5nIGNvZGUuIFbDrCB24bqteSwgY29kZXIgcuG6pXQgZOG7hSBt4bqvYyBs4buXaSBraGkgdmnhur90IG5oaeG7gXUgZMOybmcgdMawxqFuZyB04buxIG5oYXUuICoqQ2jDuiDDvSBy4bqxbmcgbuG6v3UgY29kZSBs4bq3cCBs4bqhaSB0csOqbiAyIGzhuqduIHRow6wgbsOqbiBz4butIGThu6VuZyBmdW5jdGlvbioqLiBW4bubaSBwdXJyciB0aGF5IHbDrCB2aeG6v3QgaMOgbSBt4bubaSB0aMOsIGNow7puZyB0YSBuw6puIG1vZGlmeSBob+G6t2Mga+G6v3QgaOG7o3AgY8OhYyBow6BtIGzhuqFpIHbhu5tpIG5oYXUKClNvIHPDoW5oIDIgY8OhY2ggdmnhur90IAoKYGBge3J9CnRpZHkobG0oU2VwYWwuTGVuZ3RoIH4gU3BlY2llcywgZGF0YSA9IGlyaXMpKQpgYGAKCgp2w6AgY8OhY2ggMiBz4butIGThu6VuZyBow6BtICoqY29tcG9zZSoqIAoKYGBge3J9CnRpZHlfbG0gPC0gY29tcG9zZSh0aWR5LCBsbSkKdGlkeV9sbShTZXBhbC5MZW5ndGggfiBTcGVjaWVzLCBkYXRhID0gaXJpcykKYGBgCgpOaMawIHbhuq15LCBi4bqxbmcgY8OhY2gga+G6v3QgaOG7o3AgaMOgbSAqKmxtKiogdsOgICoqdGlkeSoqICgqKnRoZW8gbmd1ecOqbiB04bqvYyB04burIHBo4bqjaSBzYW5nIHRyw6FpKiopIGNow7puZyB0YSBjw7MgaMOgbSAqKnRpZHlfbG0qKiBuZ+G6r24gZ+G7jW4KClPhu60gZOG7pW5nICoqYXNfbWFwcGVyKiogxJHhu4MgY29udmVydCAxICpvYmplY3QqIHNhbmcgKmZ1bmN0aW9uKiB2w6AgY8Wpbmcgc+G7rSBk4bulbmcgaMOgbSBjb21wb3NlCgpgYGB7cn0KY2xlYW5fbG0gPC0gY29tcG9zZShhc19tYXBwZXIofiBhcnJhbmdlKC54LCBkZXNjKHAudmFsdWUpKSksIAogICAgICAgICAgICAgICAgICAgIGFzX21hcHBlcih+IGZpbHRlcigueCwgcC52YWx1ZSA8IDAuMDUpKSwKICAgICAgICAgICAgICAgICAgICB0aWR5LCAKICAgICAgICAgICAgICAgICAgICBsbSkKY2xlYW5fbG0oU2VwYWwuTGVuZ3RoIH4gU2VwYWwuV2lkdGgsIGRhdGEgPSBpcmlzKQpgYGAKCiMgcGFydGlhbCgpCgpDw6FjaCB2aeG6v3QgdGjDtG5nIHRoxrDhu51uZyBraGkgdMOtbmggZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCB24bubaSB2ZWN0b3IgY8OzIGdpw6EgdHLhu4sgTkEKCmBgYHtyfQptZWFuKGFpcnF1YWxpdHkkT3pvbmUsIG5hLnJtID0gVFJVRSkKYGBgCgpT4butIGThu6VuZyBow6BtIHBhcnRpYWwgCgpgYGB7cn0KbWVhbl9uYV9ybSA8LSBwYXJ0aWFsKG1lYW4sIG5hLnJtID0gVFJVRSkKbWVhbl9uYV9ybShhaXJxdWFsaXR5JE96b25lKQpgYGAKCmvhur90IHF14bqjIHTGsMahbmcgdOG7sSDEkW/huqFuIGNvZGUgdHLDqm4gbmjGsG5nIG5n4bqvbiBn4buNbiBoxqFuIAoKPiBUaGFtIGto4bqjbzogaHR0cHM6Ly9jb2xpbmZheS5tZQ==