在 ggplot2 上用 R 中的多个代码替换进行迭代

Do iteration with multiple substitutions of code in R on ggplot2

我对在 R 中使用具有多个代码替换的迭代来创建多个 ggplot2 派生对象很感兴趣,但我无法弄清楚。请帮忙。

我使用下面的代码创建了 2 个数据集,diamonds_top300diamonds_bottom300

diamonds_top300 <- data.frame(dplyr::top_n(diamonds, 300, table))
diamonds_bottom300 <- data.frame(dplyr::bottom_n(diamonds, -300, table))

我想使用 2x2 设计创建 4 个直方图 [2(数据 = diamonds_top300 或 diamonds_bottom300)乘以 2(DV = 价格或克拉)设计,总共 4 个直方图] .

我可以使用下面的代码手动完成,并在适当的地方进行替换:

# manual histogram input
# ---- NOTE: 2 (data = diamonds_top300 or diamonds_bottom300) by 2 (DV = price or carat) design, for a total of 4 histograms

## Model 1: DV - price, data = diamonds_top300
(ggplot2::ggplot(diamonds_top300, aes(y=price))
  + ggplot2::geom_histogram(
    aes(y=..density..), 
    alpha=0.5, 
    position="identity", 
    binwidth = as.numeric(
      nclass.Sturges(diamonds_top300$price))
  )
  + geom_density(alpha=.2)
)

## Model 2: DV - price, data = diamonds_bottom300
(ggplot2::ggplot(diamonds_bottom300, aes(y=price))
  + ggplot2::geom_histogram(
    aes(y=..density..), 
    alpha=0.5, 
    position="identity", 
    binwidth = as.numeric(
      nclass.Sturges(diamonds_bottom300$price))
  )
  + geom_density(alpha=.2)
)

## Model 3: DV - y, data = diamonds_top300
(ggplot2::ggplot(diamonds_top300, aes(y=y))
  + ggplot2::geom_histogram(
    aes(y=..density..), 
    alpha=0.5, 
    position="identity", 
    binwidth = as.numeric(
      nclass.Sturges(diamonds_top300$y))
  )
  + geom_density(alpha=.2)
)

## Model 4: DV - y, data = diamonds_bottom300
(ggplot2::ggplot(diamonds_bottom300, aes(y=y))
  + ggplot2::geom_histogram(
    aes(y=..density..), 
    alpha=0.5, 
    position="identity", 
    binwidth = as.numeric(
      nclass.Sturges(diamonds_bottom300$y))
  )
  + geom_density(alpha=.2)
)

当我尝试使用函数和 mapply 来迭代此任务并减少代码长度时,它不起作用。 这是代码

# using mapply
# ---- NOTE: desired order: Model 1: DV - DVS_OF_INTEREST_list_model, data = diamonds_top300; ## Model 2: DV - DVS_OF_INTEREST_list_model, data = diamonds_bottom300; ## Model 3: DV - y, data = diamonds_top300; ## Model 4: DV - y, data = diamonds_bottom300

## creates function
function_histogram_diamonds_sub_dataset_and_DV_vary <- 
  function(DVS_OF_INTEREST_list_model, DATASET_list_model)
  {
    (ggplot2::ggplot(DATASET_list_model, aes(y=DVS_OF_INTEREST_list_model))
     + ggplot2::geom_histogram(
       aes(y=..density..), 
       alpha=0.5, 
       position="identity", 
       binwidth = as.numeric(
         nclass.Sturges(DATASET_list_model$DVS_OF_INTEREST_list_model))
     )
     + geom_density(alpha=.2)
    )
  }

## runs function with desired lists
mapply(function_histogram_diamonds_sub_dataset_and_DV_vary, DVS_OF_INTEREST_list, DATASET_list, SIMPLIFY = FALSE)

这是我得到的错误:

> mapply(function_histogram_diamonds_sub_dataset_and_DV_vary, DVS_OF_INTEREST_list, DATASET_list, SIMPLIFY = FALSE)
 Error: `data` must be a data frame, or other object coercible by `fortify()`, not a character vector
Run `rlang::last_error()` to see where the error occurred. 

有什么方法可以成功吗?任何帮助将不胜感激。

仅供参考,我使用的是 2013 Macbook Pro,配备 2.4 GHz 双核英特尔芯片、8 GB 内存、macOS big sur 11.2.2、RStudio 版本 1.4.1106 和 R 基础包 4.04。

谢谢。



这是我用于模型的代码


#### histograms ####




# Loads packages
# ---- NOTE: making plots and diamonds dataset
if(!require(ggplot2)){install.packages("ggplot2")}
# ---- NOTE: for data wrangling
if(!require(dplyr)){install.packages("dplyr")}




# dataset creation

## for dataset with top 300 rows
# ---- NOTE: selects only the top 300 rows of the dataset
diamonds_top300 <- data.frame(dplyr::top_n(diamonds, 300, table))
# ---- NOTE: gives dataset info
head(diamonds_top300)
str(diamonds_top300)
colnames(diamonds_top300)
nrow(diamonds_top300)
# ---- NOTE: gives unique values of Fixed and Random effects, and dvs
unique(diamonds_top300$price)
unique(diamonds_top300$y)
unique(diamonds_top300$cut)
unique(diamonds_top300$color)
unique(diamonds_top300$carat)
unique(diamonds_top300$clarity)
unique(diamonds_top300$depth)
unique(diamonds_top300$table)

## for dataset with bottom 300 rows
### dataset
# ---- NOTE: selects only the bottom 300 rows of the dataset
diamonds_bottom300 <- data.frame(dplyr::bottom_n(diamonds, -300, table))
# ---- NOTE: gives dataset info
head(diamonds_bottom300)
str(diamonds_bottom300)
colnames(diamonds_bottom300)
nrow(diamonds_bottom300)
# ---- NOTE: gives unique values of Fixed and Random effects, and dvs
unique(diamonds_bottom300$price)
unique(diamonds_bottom300$y)




# lists all variables/objects of interest
DVS_OF_INTEREST_list <- c("price", "carat")
DATASET_list <- c("diamonds_top300", "diamonds_bottom300")




# manual histogram input
# ---- NOTE: 2 (data = diamonds_top300 or diamonds_bottom300) by 2 (DV = price or carat) design, for a total of 4 histograms

## Model 1: DV - price, data = diamonds_top300
(ggplot2::ggplot(diamonds_top300, aes(y=price))
  + ggplot2::geom_histogram(
    aes(y=..density..), 
    alpha=0.5, 
    position="identity", 
    binwidth = as.numeric(
      nclass.Sturges(diamonds_top300$price))
  )
  + geom_density(alpha=.2)
)

## Model 2: DV - price, data = diamonds_bottom300
(ggplot2::ggplot(diamonds_bottom300, aes(y=price))
  + ggplot2::geom_histogram(
    aes(y=..density..), 
    alpha=0.5, 
    position="identity", 
    binwidth = as.numeric(
      nclass.Sturges(diamonds_bottom300$price))
  )
  + geom_density(alpha=.2)
)

## Model 3: DV - y, data = diamonds_top300
(ggplot2::ggplot(diamonds_top300, aes(y=y))
  + ggplot2::geom_histogram(
    aes(y=..density..), 
    alpha=0.5, 
    position="identity", 
    binwidth = as.numeric(
      nclass.Sturges(diamonds_top300$y))
  )
  + geom_density(alpha=.2)
)

## Model 4: DV - y, data = diamonds_bottom300
(ggplot2::ggplot(diamonds_bottom300, aes(y=y))
  + ggplot2::geom_histogram(
    aes(y=..density..), 
    alpha=0.5, 
    position="identity", 
    binwidth = as.numeric(
      nclass.Sturges(diamonds_bottom300$y))
  )
  + geom_density(alpha=.2)
)



# using mapply
# ---- NOTE: desired order: Model 1: DV - DVS_OF_INTEREST_list_model, data = diamonds_top300; ## Model 2: DV - DVS_OF_INTEREST_list_model, data = diamonds_bottom300; ## Model 3: DV - y, data = diamonds_top300; ## Model 4: DV - y, data = diamonds_bottom300

## creates function
function_histogram_diamonds_sub_dataset_and_DV_vary <- 
  function(DVS_OF_INTEREST_list_model, DATASET_list_model)
  {
    (ggplot2::ggplot(DATASET_list_model, aes(y=DVS_OF_INTEREST_list_model))
     + ggplot2::geom_histogram(
       aes(y=..density..), 
       alpha=0.5, 
       position="identity", 
       binwidth = as.numeric(
         nclass.Sturges(DATASET_list_model$DVS_OF_INTEREST_list_model))
     )
     + geom_density(alpha=.2)
    )
  }

## runs function with desired lists
mapply(function_histogram_diamonds_sub_dataset_and_DV_vary, DVS_OF_INTEREST_list, DATASET_list, SIMPLIFY = FALSE)

这样的事情怎么样:

function_histogram_diamonds_sub_dataset_and_DV_vary <- 
  function(DVS_OF_INTEREST_list_model, DATASET_list_model)
  {require(ggplot2)
    ggplot(DATASET_list_model, aes_string(x=DVS_OF_INTEREST_list_model))+ 
       geom_histogram(
         aes(y=..density..), 
         alpha=0.5, 
         position="identity", 
         binwidth=nclass.Sturges)+ 
      geom_density(alpha=.2)
    
  }

hists <- purrr::map2(list("price", "price", "y", "y"), 
     list(diamonds_top300, diamonds_bottom300, diamonds_top300, diamonds_bottom300), 
     ~function_histogram_diamonds_sub_dataset_and_DV_vary(.x, .y))

do.call(cowplot::plot_grid, hists)

函数必须稍微清理一下。如果您尝试传入变量的字符串名称,则需要使用 aes_string()。您还需要在美学中将感兴趣的变量定义为 x。我不确定 Sturges 的休息是否在这里起到了作用,但这很容易在代码中更改。