2017-05-07 11 views
1

次のdplyrタスクを実行しようとしていますが、関数内で実行しています。2つの変数を持つdplyr関数

library("dplyr") 

iris %>% 
    group_by(Species) %>% 
    summarise(N = sum(Petal.Width == 0.2, na.rm = T)) 

私は以下の行に沿って考えていましたが、構文が不明なため完全ではありません。

getSummary <- function(varName,level) { 
    summary <- iris %>% 
     group_by(Species %>% 
     summarise_(N = interp(~sum(var == ilevel, na.rm = T), 
        var = as.name(varName)))) 
    sums <- summary$N  
} 

この場合、レベルは数値0.2です。値が文字「0.2」の場合、変更はありますか?

+0

あなたの関数のパラメータのようになります。 'level'ですが、' summarize'に 'ilevel'を使用していますか? – neilfws

+0

'group_by'に括弧がないので、' summary'を返すか、最初に変数として格納しないでください。 – alistaire

答えて

3

dplyrはan rlang-powered oneにlazyeval搭載NSEシステムからの切り替えの過程です。 (すぐにCRANてthe GitHub versionを通じて利用可能、と)新バージョンでは、古いlazyeval構文を使用するには

library(dplyr) 

getSummary <- function(varName, level) { 
    varName <- enquo(varName) # parse and quote variable name 
    iris %>% 
     group_by(Species) %>% 
     summarise(N = sum((!!varName) == level), # unquote with !! to use 
        var = rlang::quo_text(varName)) # turn quosure to string 
} 

getSummary(Petal.Width, 0.2) 
#> # A tibble: 3 × 3 
#>  Species  N   var 
#>  <fctr> <int>  <chr> 
#> 1  setosa 29 Petal.Width 
#> 2 versicolor  0 Petal.Width 
#> 3 virginica  0 Petal.Width 

# or make it accept strings 
getSummary <- function(varName, level) { 
    iris %>% 
     group_by(Species) %>% 
     summarise(N = sum((!!rlang::sym(varName)) == level), 
        var = varName) 
} 

getSummary('Sepal.Length', 5.0) 
#> # A tibble: 3 × 3 
#>  Species  N   var 
#>  <fctr> <int>  <chr> 
#> 1  setosa  8 Sepal.Length 
#> 2 versicolor  2 Sepal.Length 
#> 3 virginica  0 Sepal.Length 

を使用することができ、それは

getSummary <- function(varName, level) { 
    iris %>% 
     group_by(Species) %>% 
     summarise_(N = lazyeval::interp(~sum(x == y), # formula to substitute into 
             x = lazyeval::lazy(varName), # substituted but unevaluated name 
             y = level), # value to substitute 
        var = ~lazyeval::expr_text(varName)) # convert expression to string (equivalent to `deparse(substitute(...))`) 
} 

getSummary(Sepal.Length, 5.0) 
#> # A tibble: 3 × 3 
#>  Species  N   var 
#>  <fctr> <int>  <chr> 
#> 1  setosa  8 Sepal.Length 
#> 2 versicolor  2 Sepal.Length 
#> 3 virginica  0 Sepal.Length 

# or make it accept strings 
getSummary <- function(varName, level) { 
    iris %>% 
     group_by(Species) %>% 
     summarise_(N = lazyeval::interp(~sum(x == y), 
             x = as.name(varName), 
             y = level), 
        var = ~varName) 
} 

getSummary('Petal.Width', 0.2) 
#> # A tibble: 3 × 3 
#>  Species  N   var 
#>  <fctr> <int>  <chr> 
#> 1  setosa 29 Petal.Width 
#> 2 versicolor  0 Petal.Width 
#> 3 virginica  0 Petal.Width 
+0

ありがとうございます。私の元の質問に構文を得るための提案。私はvarNameとレベルの両方に "as.name"のようなものを指定する方法がわかりません。 – julieth

+0

この時点でlazyevalの仕組みを解読するのはあまり意味がありませんが、どのように見えるのかを編集しました。 [ここには古いビネットがあります](https://cran.r-project.org/web/packages/dplyr/vignettes/nse.html)に少し説明があります。一番下の行は、すべてが数式またはその他の方法で引用されなければならないということです。実際には文字列で終わるためには、文字列を引用する必要があります。 – alistaire

+0

...明確にするために、引用符で囲まれていない式の代わりに変数の文字列を渡す場合は、 'as.name'が必要です。 rlangは 'rlang :: sym'です。 – alistaire

関連する問題