2016-11-01 5 views
4

条件文をdplyr :: summarize()のさまざまな部分で動作させることはできますか?dplyr :: summarize()のさまざまな部分を条件付きで計算できますか?

私はirisのデータを使って作業しており、要約を出力していますが、要求されたときにはSepal.Lengthの平均値だけを含めたいと考えています。だから私のような何かができる:

data(iris) 
include_length = T 
if (include_length) { 
    iris %>% 
    group_by(Species) %>% 
    summarize(mean_sepal_width = mean(Sepal.Width), mean_sepal_length = mean(Sepal.Length)) 
} else { 
    iris %>% 
    group_by(Species) %>% 
    summarize(mean_sepal_width = mean(Sepal.Width)) 

} 

しかし、それが重複する必要がないように、パイプライン内の条件を実装する方法はありますか?

答えて

4

dplyrのSE関数の.dotsパラメータを使用して、プログラムでエバリュエートすることができます。

library(dplyr) 

take_means <- function(include_length){ 
    iris %>% 
     group_by(Species) %>% 
     summarize_(mean_sepal_width = ~mean(Sepal.Width), 
        .dots = if(include_length){ 
         list(mean_sepal_length = ~mean(Sepal.Length)) 
        }) 
} 

take_means(TRUE) 
#> # A tibble: 3 × 3 
#>  Species mean_sepal_width mean_sepal_length 
#>  <fctr>   <dbl>    <dbl> 
#> 1  setosa   3.428    5.006 
#> 2 versicolor   2.770    5.936 
#> 3 virginica   2.974    6.588 

take_means(FALSE) 
#> # A tibble: 3 × 2 
#>  Species mean_sepal_width 
#>  <fctr>   <dbl> 
#> 1  setosa   3.428 
#> 2 versicolor   2.770 
#> 3 virginica   2.974 
+1

@フランクええ、どのようにしてそれがより明白になったのか判断できませんでしたが、それは機能としてはもっと意味があると私は編集しました。 – alistaire

+1

これは、トリックを行う必要がありますが、私はおそらく以前の編集を使用して終了します。ありがとう! –

1

conditional evaluation with magrittrです。

可能な解決策:

ベースRで
library(magrittr) 
library(dplyr) 

data(iris) 
include_length = T 

iris %>% 
    group_by(Species) %>% 
    { if (include_length) {summarize(., mean_sepal_width = mean(Sepal.Width), mean_sepal_length = mean(Sepal.Length))} 
    else {summarize(., mean_sepal_width = mean(Sepal.Width))} 
    } 
+0

私は彼らが 'mean_sepal_width = mean(Sepal.Width)'を2回書くことを避けたかったと思います。 – Frank

+0

これは良いですが、私の実際の使用例では、サマリステートメントは7つまたは8つの異なる変数を計算するので、不可能かもしれませんが理想的にはその重複は避けてください。 –

3

、あなたがc(x, if (d) y)を行うことができますし、dの値に応じて、あなたは2番目の要素は含まれたり、結果から除外取得します。 xおよびyは、ベクターまたはリストにすることができます。

リターン式がリストであるので、このトリックは、data.tableで動作します:.()DT[...]インサイド

library(data.table) 
f = function(d) data.table(iris)[, c(
    .(mw = mean(Sepal.Width)), 
    if(d) .(ml = mean(Sepal.Length)) 
), by=Species] 

使用

> f(TRUE) 
     Species mw ml 
1:  setosa 3.428 5.006 
2: versicolor 2.770 5.936 
3: virginica 2.974 6.588 
> f(FALSE) 
     Species mw 
1:  setosa 3.428 
2: versicolor 2.770 
3: virginica 2.974 

list()の省略形です。パイプを叩きたい理由があるかもしれませんが、このオプションは検討する価値があると思います。

0

A少しハック方法:これは、そうでない場合は、平均include_length == TRUE場合でカラムを作成し、NA

iris %>% 
    group_by(Species) %>% 
    summarise(mean_sepal_length=if(include_length) mean(Sepal.Length) else NA, 
       mean_sepal_width=mean(Sepal.Width)) 

。この問題が発生した場合は、後処理でNA列を削除することができます。

関連する問題