2

目的: 最初の引数としてデータ フレームを受け取り、次に 2 つの追加の引数 (引数のリスト) を受け取る dplyr::select関数を作成して、関数が 2 つのデータ フレームを返すようにします。

これが実際の例です

my_select <- function(.data, df1, df2) {
  DF1 <- dplyr::select(.data, rlang::UQS(df1))
  DF2 <- dplyr::select(.data, rlang::UQS(df2))
  list(DF1 = DF1, DF2 = DF2)
}

working_eg <-
  my_select(mtcars,
          df1 = alist(dplyr::contains("r"), dplyr::matches("^.p.*")),
          df2 = alist(disp))

str(working_eg, max.length = 1L)

## List of 2
##  $ DF1:'data.frame': 32 obs. of  5 variables:
##   ..$ drat: num [1:32] 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
##   ..$ gear: num [1:32] 4 4 4 3 3 3 3 4 4 4 ...
##   ..$ carb: num [1:32] 4 4 1 1 2 1 4 2 2 4 ...
##   ..$ mpg : num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
##   ..$ hp  : num [1:32] 110 110 93 110 175 105 245 62 95 123 ...
##  $ DF2:'data.frame': 32 obs. of  1 variable:
##   ..$ disp: num [1:32] 160 160 108 258 360 ...

df1私は、引数とdf2を取ることを好むだろうlistないalist. ただし、my_select引数が次の場合、関数は失敗します。list

my_select(mtcars,
          df1 = list(dplyr::contains("r"), dplyr::matches("^.p.*")),
          df2 = list(disp))
## Error: Variable context not set

.の代わりalistに.alistlist

これを修正するため に、、 、rlang::UQrlang::UQE、の組み合わせをいくつか試しました。私が最良のアプローチだと思ったのは次のとおりです。rlang::UQSrlang::quorlang::enquosrlang::quos

my_select2 <- function(.data, df1, df2) {
  DF1 <- dplyr::select(.data, rlang::UQS(rlang::quos(df1)))
  DF2 <- dplyr::select(.data, rlang::UQS(rlang::quos(df2)))
  list(DF1 = DF1, DF2 = DF2)
}

my_select2(mtcars,
          df1 = list(dplyr::contains("r"), dplyr::matches("^.p.*")),
          df2 = list(disp))
## Error: `df1` must resolve to integer column positions, not a list

rlang パッケージをdplyrで使用して、引数が 経由で渡された場合my_select2と同じオブジェクトをの構文が返すようにする方法はありますか?my_selectalist

packageVersion("dplyr")
# [1] ‘0.7.4’
packageVersion("rlang")
# [1] ‘0.1.2’
4

1 に答える 1

0

@MrFlick のコメントは、問題を解決して API を改善する必要があることを思い出させてくれました。

my_select3 <- function(.data, df1, df2) {
  DF1 <- dplyr::select(.data, rlang::UQS((df1)))
  DF2 <- dplyr::select(.data, rlang::UQS((df2)))
  list(DF1 = DF1, DF2 = DF2)
}

working_eg2 <-
  my_select3(mtcars,
            df1 = dplyr::vars(dplyr::contains("r"), dplyr::matches("^.p.*")),
            df2 = dplyr::vars(disp))

all.equal(working_eg, working_eg2)
# [1] TRUE
于 2017-10-23T19:16:37.323 に答える