2017-03-03 8 views
1

私は複雑なdplyr構造体を関数呼び出し内に持っています。入力は、sと呼ばれる追加の列を持つことができるデータフレームです。この列が利用可能な場合は、標準列にこの列を追加してグループ化します。 現時点では、ifステートメントで列がデータフレーム内にあるかどうかを確認し、グループ化を異なる方法で解決しました。グループ分け後、私は両方の種類のデータに対して同じコードを持っています。列がないdplyrのグループ化

これを行うより洗練された方法がありますか?私の元の関数では、私はsummarise関数で計算するいくつかの変数があり、私は別々に両方の部分を維持したくありません。

ここは例です。

library(dplyr) 
df1 <- data.frame(s=rep(c('a','b'), each=10), 
        p=rep(letters[1:5], 4), 
        v=runif(20)) 
df2 <- data.frame(p=rep(letters[1:5], each=4), 
        v=runif(20)) 

avgP <- function(df) { 
    if('s' %in% names(df)) { 
    df %>% 
     group_by(s, p) %>% 
     summarise(avg=mean(v)) 
    } else { 
    df %>% 
     group_by(p) %>% 
     summarise(avg=mean(v)) 
    } 
} 

avgP(df1) 
avgP(df2) 

私の推奨されるソリューションは、私がdf2上で作業するときgroup_byはちょうどのみpで不足している列とするグループを無視しているようなものになるだろう。

+0

を使用することができますが、各データセット内の同じ変数はありますか? (もちろん「s」とは別に)?たぶんSEを使用する – Sotos

+0

SEの意味は?はい、基本的に同じです。 – drmariod

+2

[このリンクをご覧ください](https://cran.r-project.org/web/packages/dplyr/vignettes/nse.html)。また、@ akrunの答えはSE – Sotos

答えて

3

我々はintersect

avgP1 <- function(df){ 
    df %>% 
    group_by_(.dots = intersect(names(df), c("s", "p"))) %>% 
    summarise(avg=mean(v)) 
} 

avgP1(df1) 
avgP1(df2) 
+1

うわー、これはとても良い解決策です。グループ化列がまったく存在しない場合、これを同様の方法で使用できますか?グループ化するかどうかをグループ化するには... – drmariod

+0

@drmariod現在の設定では、 's'または 'p'列がない場合、 'v'全体の平均を返します。つまり、 'df3 < - df2 [-1]; avgP1(df3)#avg 1 0.5880442;平均(df3 $ v) #[1] 0.5880442' ' – akrun

+1

これは完璧です。私はこれらすべての機能を認識していませんでしたが、名前の競合を助けると思っていました...私の元の関数では、 'tidyr :: gather'も使用して、' tidyr :: gather_'私にはもっと可能性があります。再度、感謝します! – drmariod

関連する問題