在 pdf 中保存每列的密度图

Save density plot for each column in pdfs

我想为数据集的每个数字列创建一个密度图,然后将输出保存为列名。

为了保持数据的匿名性,我将使用 mtcars

我理想的输出是密度图,保存如下:

mpg.pdf
cyl.pdf
disp.pdf
hp.pdf
drat.pdf
qsec.pdf
vs.pdf
am.pdf
gear.pdf
carb.pdf

我的尝试,显然行不通..

library(dplyr)
library(ggplot2)
col_tmp <- colnames(mtcars)

make_plots <- function(col){
  column <- mtcars %>% select(col) 
  col_plot <- column %>%
    ggplot( aes(x=col)) +
    geom_density(fill="#69b3a2", color="#e9ecef", alpha=0.8)
  
  ggsave(col_plot, file="col.pdf")
}

lapply(mtcars, make_plots(col_tmp))

我认为问题可能出在将向量中的列名解析到函数中?我试过使用 [[col]] 但这也不起作用...

挑战在于函数内部 col 是一个包含列名称的文本字符串。这不是列的名称。

以下将文本字符串转换为列名的工作:

my_string = "gear"

mtcars %>%
  mutate(new = 2*!!sym(my_string)) %>%
  select(new, !!sym(my_string))

相当于:

mtcars %>%
  mutate(new = 2*gear) %>%
  select(new , gear)

在此基础上,我将你的功能修改如下:

make_plots <- function(col){
  column <- mtcars %>%
    select(!!sym(col)) %>%
    rename(only_column = !!sym(col))
  # now regardless of `col` the name of the column is 'only_col'

  col_plot <- column %>%
    ggplot(aes(x = only_column)) +
    geom_density(fill = "#69b3a2", color = "#e9ecef", alpha = 0.8)
  
  file_name = paste0(col, ".pdf")
  ggsave(col_plot, file = file_name)
}

有几种方法。一种是使用 .data 结构。

make_plots <- function(col){
  col_plot <- mtcars %>%
    ggplot(aes(x = .data[[col]])) +
    geom_density(fill = "#69b3a2", color = "#e9ecef", alpha = 0.8)
  
  file_name <- paste0(col, ".pdf")
  ggsave(col_plot, file = file_name)
}

lapply(col_tmp, make_plots)

请注意,您的 lapply 不起作用,并且 select 没有必要编辑该列。

您可以 plot density 分布函数并使用 polygon 来遮蔽它们。在 '#69b3a2cc' 中添加 'cc' 定义了 0.8 的 alpha。

make_plots <- \(x) {
  pdf(paste0(x, '.pdf'))
  d <- density(mtcars[[x]])
  plot(d, main=x, col='#e9ecef')
  polygon(d, col='#69b3a2cc')
  dev.off()
}

要仅对数字列进行子集化,请查看 'numeric' 中的列 inherits 并首先保存布尔向量。

num_cols <- sapply(mtcars, inherits, 'numeric')
lapply(names(mtcars[num_cols]), make_plots)

给予

.pdf 看起来像这样:

您可以使用 paste0(path, x, '.pdf').

之类的方式在 pdf 中明确指定 file= 路径