R-如何使用参数列表筛选数据以生成多个数据帧和图形

R-如何使用参数列表筛选数据以生成多个数据帧和图形,r,for-loop,plot,filter,assign,R,For Loop,Plot,Filter,Assign,我正在寻找一种使用过滤器参数列表来生成不同对象的方法。我有一个数据集,我想为它制作几个图表。但是,我希望所有这些图都基于数据集的子集。为了便于说明,我提供了以下数据 df <- data.frame(type = c("b1", "b2", "b1", "b2"), yield = c("15", "10", "5", "0"), temperature = c("2", "21", "26", "13"),

我正在寻找一种使用过滤器参数列表来生成不同对象的方法。我有一个数据集,我想为它制作几个图表。但是,我希望所有这些图都基于数据集的子集。为了便于说明,我提供了以下数据

df <- data.frame(type = c("b1", "b2", "b1", "b2"),
                 yield = c("15", "10", "5", "0"),
                 temperature = c("2", "21", "26", "13"),
                 Season = c("Winter", "Summer", "Summer", "Autumn"),
                 profit = c(TRUE, TRUE, FALSE, FALSE))
但是,这不起作用,因为filter函数不接受作为参数,例如brand=='b1'。我想要的是brand=='b1',所以filter接受它作为参数。有人有这样做的想法吗

另外,作为一个额外的问题,我想自动化整个过程,并以一个组合图结束,因此grid.arrange在末尾。当然,我可以通过一些长度过滤器的设计来自动化ncol和nrow。但是如何在网格中获得所有生成的图呢?这应该在for循环之外,对吗?有什么想法吗

您可以通过使用eval和parse来完成

此外,对自定义函数的lappy听起来比带有assign的for循环更合理。结果是ggplot对象的列表

要将所有图表都设置在一起,grid.arrange从gridExtra包可以正常工作。您只需要将图表列表分配给名为grobs的参数

我对您的数据做了几处更改:收益率必须是数字,因为您使用的过滤器仅适用于数字向量,最后一个空的过滤器现在等于TRUE[我想您应该考虑所有因素]

您可以使用eval和parse来完成

此外,对自定义函数的lappy听起来比带有assign的for循环更合理。结果是ggplot对象的列表

要将所有图表都设置在一起,grid.arrange从gridExtra包可以正常工作。您只需要将图表列表分配给名为grobs的参数


我对您的数据做了一些更改:收益率必须是数字,因为您使用的过滤器仅适用于数字向量,最后一个空的过滤器现在等于TRUE[我想您应该考虑所有因素]

而不是将过滤器存储为字符串,最好把它们储存起来。比如说

library(rlang)
filters <- quos(type=='b1',
             profit,
             Season=='Summer',
             profit==FALSE,
             yield >= 10,
             TRUE)

与其将过滤器存储为字符串,不如将其存储为quosures。比如说

library(rlang)
filters <- quos(type=='b1',
             profit,
             Season=='Summer',
             profit==FALSE,
             yield >= 10,
             TRUE)

假设最后注释中的输入数据修复了问题中显示的数据中的一些不一致之处,使温度和产量为数值,并将利润==FALSE提高到公正!利润定义一个函数图,该函数图包含一个过滤器、df子集并绘制它。然后将其应用于每个过滤器,并使用grid.arrange。这使用了ggplot2和gridExtra,但没有额外的包,也没有显式地使用eval

grid.arrange线的另一种替代方法是cowplot::plot\u gridplotlist=plots,它提供了稍微不同的布局

library(ggplot2)
library(gridExtra)

Plot <- function(x) {
  data <- do.call("subset", list(df, parse(text = x)))
  ggplot(data, aes(temperature, yield)) + geom_line() + geom_point() + ggtitle(x)
}

plots <- Map(Plot, filters)
do.call("grid.arrange", plots)
笔记
假设最后注释中的输入数据修复了问题中显示的数据中的一些不一致之处,使温度和产量为数值,并将利润==FALSE提高到公正!利润定义一个函数图,该函数图包含一个过滤器、df子集并绘制它。然后将其应用于每个过滤器,并使用grid.arrange。这使用了ggplot2和gridExtra,但没有额外的包,也没有显式地使用eval

grid.arrange线的另一种替代方法是cowplot::plot\u gridplotlist=plots,它提供了稍微不同的布局

library(ggplot2)
library(gridExtra)

Plot <- function(x) {
  data <- do.call("subset", list(df, parse(text = x)))
  ggplot(data, aes(temperature, yield)) + geom_line() + geom_point() + ggtitle(x)
}

plots <- Map(Plot, filters)
do.call("grid.arrange", plots)
笔记
筛选器需要一个条件,该条件必须始终是逻辑的。不清楚你所说的因素是什么意思。。。从这个意义上说。总的来说,我强烈反对以这种方式使用assign,通常类似list的东西更好,更符合R习惯用法。也许按照我编写脚本的方式,列表中的元素作为类型因子提供给过滤器。这就是我想解释的。我可以通过eval和parse绕过这个问题。filter需要一个条件,它必须始终是逻辑的。不清楚你所说的因素是什么意思。。。从这个意义上说。总的来说,我强烈反对以这种方式使用assign,通常类似list的东西更好,更符合R习惯用法。也许按照我编写脚本的方式,列表中的元素作为类型因子提供给过滤器。这就是我想解释的。我可以用eval和parse绕过这个问题。你介意在这里解释一下使用!!和我看到了相同的一组图,所以我想知道在什么情况下,这两个操作符会给出不同的结果。我想在这种情况下,它们会是相同的。一般来说可以扩展到多个参数,而!!将扩展到只有一个。您介意在这里解释一下使用!!和我看到了相同的一组图,所以我想知道在什么情况下,这两个操作符会给出不同的结果。我想在这种情况下,它们会是相同的。一般来说可以扩展到多个参数,而!!将扩展t
哦,只有一个。谢谢你,这对我来说非常有效。是的,我这边有一些输入错误:产量必须是数字的,我指的是filterTRUE。谢谢,这对我来说非常有效。是的,我这边也有一些错误:收益率必须是数字的,而对于过滤器,我指的是过滤器真的。
library(dplyr)
library(purrr)
library(ggplot2)
map(filters, ~df %>% filter(!!!.x) %>% 
      ggplot(aes(x = temperature, y = yield)) + geom_point())
library(ggplot2)
library(gridExtra)

Plot <- function(x) {
  data <- do.call("subset", list(df, parse(text = x)))
  ggplot(data, aes(temperature, yield)) + geom_line() + geom_point() + ggtitle(x)
}

plots <- Map(Plot, filters)
do.call("grid.arrange", plots)
df <- data.frame(brand = c("b1", "b2", "b1", "b2"),
                 yield = c(15, 10, 5, 0),
                 temperature = c(2, 21, 26, 13),
                 Season = c("Winter", "Summer", "Summer", "Autumn"),
                 profit = c(TRUE, TRUE, FALSE, FALSE))

filters <- c("brand=='b1'",
             "profit",
             "Season=='Summer'",
             "!profit",
             "yield >= 10",
             TRUE)