使用dplyr

时间:2017-09-25 09:58:34

标签: r function loops dplyr

我创建了很多数据框,如下所示:

df <- data %>%    select(var1,var2,var3,var4) %>%    group_by(var3,var4) %>%    filter(var2 ==1) %>%    summarise(var1 = mean(var1))

每个数据帧的输出是var1和var4对变量分组后的var1的平均值,并根据不同的变量对其进行过滤。

我在上面提供的数据帧和我代码中其余部分的唯一区别是过滤变量。

因为我想要一个漂亮的表来呈现我的输出,所以我使用left_join来按照我想要的方式合并和排列数据帧。

虽然我已完成分析并得到了我想要的输出......

我必须使用许多其他变量过滤变量,最后我创建了20个数据帧。

所以我的问题是:

有没有其他方法可以使用函数或循环一次创建所有这些数据框?类似的东西:

df [i]&lt; - ....我在1-20 ..

也许我应该使用我想要过滤的变量定义和数组,然后命名这个数组?

任何想法都欢迎!

提前致谢。

1 个答案:

答案 0 :(得分:0)

因为看起来您的过滤器不是互斥的(也就是说,数据点可以在多个过滤组中),我认为您最好的选择是制作过滤器的矢量,然后循环向量(虽然我会使用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

代码应该对任意数量的过滤器,您选择的任何名称,任意数量的分组变量(或组)都是健壮的。如果要返回多个变量,则需要更加小心,但在这种情况下,宽幅格式可能是不可取的。