Zero's Blog - tidyverse https://l2dy.sourceforge.io/tag/tidyverse/ ggplot2 画百分比饼图 https://l2dy.sourceforge.io/2022/04/22/ggplot2-pie-chart-with-percentage.html 2022-04-22T15:28:00+00:00 首先通过 count() 计算出各种 cut 的钻石各有多少个,存到名为 n 的列里,然后通过 mutate 计算出总和为1的占比。此时如果用 geom_col() 画图可以得出一个高度为1的堆积图。library(tidyverse) diamonds %>% count(cut) %>% mutate(p = n / sum(n)) %>% ggplot(aes("", p, fill = cut)) + geom_col() + scale_fill_brewer(type = "div")再加以 coord_polar() 变换转换为极座标,就可以画出一张饼图了。在此基础上多叠加一层 geom_text() 就实现了百分比的显示,非常灵活。diamonds %>% count(cut) %>% mutate(p = n / sum(n)) %>% mutate(labels = scales::label_percent(accuracy = 0.01)(n / sum(n))) %>% ggplot(aes("", p, fill = cut)) + geom_col() + geom_text(aes(label = labels), position = position_stack(0.5)) + coord_polar("y") + scale_fill_brewer(type = "div")如果不想显示极座标轴和灰色背景,可以通过加上 theme_void() 来实现。对于重叠的文字则是可以用 ggrepel 打散,最终效果如图。 展开 Tiddle 中的 JSON 字段 https://l2dy.sourceforge.io/2022/04/20/tidyverse-unnest-json.html 2022-04-20T15:47:20+00:00 tidyr 本身就提供了 unnest() 系列函数,可以用于展开嵌套的数据结构。配合 fromJSON() 使用就可以实现 JSON 字段的展开。library(tidyverse) library(jsonlite) spread_all <- function(data, cols) { data %>% mutate(across(all_of(cols), function(x) map(x, fromJSON))) %>% unnest_wider(all_of(cols)) } # 用法 df %>% spread_all(c("x", "y"))为了加速 JSON 的解析,我们可以引入 furrr 包来实现并发解析。library(furrr) # make future_map parallel plan(multisession) spread_all <- function(data, cols) { data %>% mutate(across(all_of(cols), function(x) future_map(x, fromJSON))) %>% unnest_wider(all_of(cols)) } Tidyverse 读取多个同格式 csv 文件 https://l2dy.sourceforge.io/2022/04/17/tidyverse-read-multiple-csv-files.html 2022-04-17T03:44:00+00:00 如何将多个同样格式的 csv 文件合并读取到一个 tibble 里呢?很自然的会想到先用 read_csv() 分别读取每个文件,再用 reduce(rbind) 聚合到一起。这样确实能用,但对于大数据集来说性能很差。readr 从 2.0.0 开始原生支持同时读取多个文件的功能,只需要把文件名字符串向量里传给 file 参数就行。实测在数据量很大的时候和 rbind 相比可以显著减少读取时间。这个功能在 readr 包的文档中没有描述,导致我走了不少弯路才发现 readr 原生就支持多文件读取。另外 vroom 从 1.0.0 开始就原生支持了这个功能,用法一样不过 vroom 对于文件中的字符数据是懒加载的,在某些场景下可以提升性能。具体能否提升性能要看使用方式了,可以用 system.time({}) 实测一下。