将嵌套的 For 循环转换为 R 中的 `sapply()`

Converting a Nested For Loop into `sapply()` in R

我一直在尝试使用嵌套的 for 循环创建一系列 coplots,但循环花费的时间太长 运行(原始数据集非常大)。我看过类似的问题,他们建议使用 sapply 函数,但我仍然不清楚如何在两者之间进行转换。我知道我需要创建一个绘图函数来使用(见下文),但我不明白的是如何嵌套的 for 循环的 i 和 j 进入 sapply arguments。

我制作了一些示例数据,我一直在使用的嵌套 for 循环和我创建的绘图函数如下所示。谁能告诉我如何将嵌套的 for 循环转换为 sapply 参数。我一直在 R 中完成所有这些工作。非常感谢

y = rnorm(n = 200, mean = 10, sd = 2)
x1 = rnorm(n = 200, mean = 5, sd = 2)
x2 = rnorm(n = 200, mean = 2.5, sd = 2)
x3 = rep(letters[1:4], each = 50)
x4 = rep(LETTERS[1:8], each = 25)
dat = data.frame(y = y, x1 = x1, x2 = x2, x3 = x3, x4 = x4)

for(i in dat[, 2:3]){
  for(j in dat[, 4:5]){
    coplot(y ~ i | j, rows = 1, data = dat)
  }
}

coplop_fun = function(data, x, y, x, na.rm = TRUE){
  coplot(.data[[y]] ~ .data[[x]] | .data[[z]], data = data, rows = 1)
}

我们可以结合使用函数 expand.gridformulaapply 将字符列名称接受到 coplot.

# combinations of column names for plotting
vars <- expand.grid(y = "y", x = c("x1", "x2"), z = c("x3", "x4"))

# cycle through column name variations, construct formula for each combination
apply(vars, MARGIN = 1,
    FUN = function(x) coplot(
        formula = formula(paste(x[1], "~", x[2], "|", x[3])),
        data = dat, row = 1
    )
)
 

我认为您可以在这里使用 mapply 而不是 sapplymapply 类似于 sapply 但允许您传递两个输入而不是一个。

y = rnorm(n = 200, mean = 10, sd = 2)
x1 = rnorm(n = 200, mean = 5, sd = 2)
x2 = rnorm(n = 200, mean = 2.5, sd = 2)
x3 = rep(letters[1:4], each = 50)
x4 = rep(LETTERS[1:8], each = 25)
dat = data.frame(y = y, x1 = x1, x2 = x2, x3 = x3, x4 = x4)

for(i in dat[, 2:3]){
  for(j in dat[, 4:5]){
    coplot(y ~ i | j, rows = 1, data = dat)
  }
}

mapply(function(x,j){coplot(dat[["y"]]~x|j,rows =1)}, dat[,2:3],dat[,4:5])

这是@nya 的解决方案的 tidyverse 版本,其中包含 expand.grid()apply()ds_plot_parameters 中的每一行代表一个图。 equation 变量是最终传递给 coplot().

的字符串

每个方程都传递给 purrr::walk(),然后调用 coplot() 每人制作一张图表。 as.equation() 将字符串转换为等式。

ds_plot_parameters <- 
  tidyr::expand_grid(
    v = c("x1", "x2"),
    w = c("x3", "x4")
  ) |> 
  dplyr::mutate(
    equation = paste0("y ~ ", v, " | ", w),
  )

ds_plot_parameters$equation |> 
  purrr::walk(
    \(e) coplot(as.formula(e), rows = 1, data = dat)
  )

肉汁: 如果您想为图表提供更多输入,请展开 ds_plot_parameters 以包括图表和轴标题等其他内容。

ds_plot_parameters <- 
  tidyr::expand_grid(
    v = c("x1", "x2"),
    w = c("x3", "x4")
  ) |> 
  dplyr::mutate(
    equation  = paste0("y ~ ", v, " | ", w),
    label_y   = "Outcome (mL)",
    label_x   = paste(v, " (log 10)")
  )

ds_plot_parameters |>
  dplyr::select(
    # Make sure this order exactly matches the function signature
    equation,
    label_x,
    label_y,
  ) |>
  purrr::pwalk(
    .f = \(equation, label_x, label_y) {
      coplot(
        formula = as.formula(equation), 
        xlab    = label_x,
        ylab    = label_y,
        rows    = 1, 
        data = dat
      )
    }
  )


ds_plot_parameters
# # A tibble: 4 x 5
#   v     w     equation    label_y      label_x     
#   <chr> <chr> <chr>       <chr>        <chr>       
# 1 x1    x3    y ~ x1 | x3 Outcome (mL) x1  (log 10)
# 2 x1    x4    y ~ x1 | x4 Outcome (mL) x1  (log 10)
# 3 x2    x3    y ~ x2 | x3 Outcome (mL) x2  (log 10)
# 4 x2    x4    y ~ x2 | x4 Outcome (mL) x2  (log 10)