因为您的过滤器似乎不是互斥的(也就是说,一个数据点可以位于多个过滤组中),我认为您最好的选择可能是制作一个过滤器的向量,然后循环遍历它矢量(虽然我会使用 lapply 而不是 for 循环)。
由于您没有提供可重复的数据集或您使用的过滤器的想法,我将使用内置的 iris 数据并仅按物种分组(代码对于多个分组变量的工作方式相同)。
首先,这是一组过滤器:
irisFilters <-
c(Long = quote(Sepal.Length > 6 | Petal.Length > 4)
, Wide = quote(Sepal.Width > 3 | Petal.Width > 1.5)
, Boxy = quote((Sepal.Width / Sepal.Length) > 0.5)
)
请注意,这些完全是任意的(并且可能根本没有意义),但它们应该让您了解什么是可能的。重要的是,我使用 quote 并不是为了让我以后可以将它们传递给 filter 步骤。
然后,使用lapply 逐步检查每个过滤条件,使用!! 告诉 dplyr 解释变量内部的内容。在这里,我只是取Petal.Length 的平均值,因为这似乎与您的用例相匹配
irisSummaries <-
irisFilters %>%
lapply(function(thisFilter){
iris %>%
filter(!! thisFilter) %>%
group_by(Species) %>%
summarise(Petal.Length = mean(Petal.Length))
})
这将返回一个列表,其中包含与您的每个条件匹配的汇总结果,如下所示:
$Long
# A tibble: 2 x 2
Species Petal.Length
<fctr> <dbl>
1 versicolor 4.502857
2 virginica 5.552000
$Wide
# A tibble: 3 x 2
Species Petal.Length
<fctr> <dbl>
1 setosa 1.480952
2 versicolor 4.730000
3 virginica 5.572340
$Boxy
# A tibble: 3 x 2
Species Petal.Length
<fctr> <dbl>
1 setosa 1.462000
2 versicolor 4.290909
3 virginica 5.320000
然后,您可以将它们组合到一个表中,使用您为它们分配的名称(在创建过滤器向量时)作为标识符:
longSummaries <-
irisSummaries %>%
bind_rows(.id = "Filter")
返回:
Filter Species Petal.Length
<chr> <fctr> <dbl>
1 Long versicolor 4.502857
2 Long virginica 5.552000
3 Wide setosa 1.480952
4 Wide versicolor 4.730000
5 Wide virginica 5.572340
6 Boxy setosa 1.462000
7 Boxy versicolor 4.290909
8 Boxy virginica 5.320000
然后您可以使用spread 为每个过滤器创建一个列:
wideSummaries <-
longSummaries %>%
spread(Filter, Petal.Length)
返回:
Species Boxy Long Wide
* <fctr> <dbl> <dbl> <dbl>
1 setosa 1.462000 NA 1.480952
2 versicolor 4.290909 4.502857 4.730000
3 virginica 5.320000 5.552000 5.572340
代码应该对任意数量的过滤器、您选择的任何名称、任意数量的分组变量(或组)都具有鲁棒性。如果您要返回多个变量,则需要更加小心,但在这种情况下,宽格式可能无论如何都是不可取的。