5

dplyr関数を使った関数を作りたいので「dplyrでプログラミング」ビネットを勉強しています。私が作成した関数を、光沢のあるアプリケーションとインタラクティブな R 作業の両方で使用したいと考えています。Shiny で使用するには、これらの関数が文字列引数を取り、sym 関数を使用してそれらをシンボルに変換するようにしたいと考えています。インタラクティブなセッションで使用するために、これらの関数に文字列を使用しなくてもよいオプションが必要です。したがって、私が作成する関数には、特定の引数が文字列かどうかを判断する方法が必要になります。

私はこれへの方法を考え出しました。それを行うためのより良いおよび/またはよりエレガントな方法があるかどうか、私はただ興味があります。

例として、「my_summarise」という単純な関数を作成しました。これは、ビネットとは異なるバージョンの関数「my_summarise」です。これは、tryCatch を使用して、group_var 引数が文字列かどうかを確認します。

library(dplyr)
df <- data.frame(g1 = c(1, 1, 2, 2, 2),
  g2 = c(1, 2, 1, 2, 1),
  a = c(1, 5, 4, 3, 2),
  b = c(3, 1, 2, 5, 4))

# df:

#  g1 g2 a b
#  1  1 1 3
#  1  2 5 1
#  2  1 4 2
#  2  2 3 5
#  2  1 2 4

my_summarise <- function(df, group_var) {

  is_string <- tryCatch(sym(group_var), error = function(group_var) group_var)

  if ("error" %in% class(is_string)) { 
    group_var <- enquo(group_var)      
  } else {
    group_var <- sym(group_var)   
  }

  df %>% group_by(!! group_var) %>% 
    summarise(a = mean(a))
}

my_summarise(df, g1)
# g1     a
# 1     3
# 2     3

my_summarise(df, "g1")
# g1     a
# 1     3
# 2     3

編集:Onyambuの答えは完璧です. 基本的な同等の関数の代わりに、いくつかの rlang 関数を使用するように微調整しました。

my_summarise <- function(df, group_var) {

  group_var <- enexpr(group_var)

  if(!is_symbol(group_var)) group_var <- sym(group_var) # instead of is.name and as.name you can use is.symbol and as.symbol or a mixture. 

  group_var <- enquo(group_var)      

  df %>% group_by(!! group_var) %>% 
    summarise(a = mean(a))
}
4

2 に答える 2