論理の流刑地

地獄の底を、爆笑しながら闊歩する

【R小ネタ】最終引数以外でも、複数の変数を非標準評価(NSE)形式で与えたい場合のやりかた。

なんか簡単そうで意外と思いつかなかったので簡易な備忘

Probrem

関数内でdplyrの諸関数をつかうときに、NSEな感じでquotationをつけずに引数を複数指定したいときがある。
そんなとき、最終の引数であれば 「...」をquos()で受け取ってから、!!!演算子をつかえばよい(下の記事参照)

ronri-rukeichi.hatenablog.com

でもそうじゃなくて、最終以外の引数で

func1( data , list( X, Y , Z) , c1, c2 ,c3)

みたいな感じでの指定がしたいときどうするのかっていう話です。

Solution

おなじことをやりたい人が海外にいたので、StackOverFlowにやりかたがあった。
(というかたいていこういう細かいこと調べたい時英語情報しか出てこない*1
stackoverflow.com

以下のようにするとよい。
例として第二引数で欲しい変数の種類を、第三引数でグルーピングに使う変数を指定する、みたいな関数を考える。

test_fun <- function( dta , vname , ...){
grp_v <- quos(...)

slct_v <-  (as.list( rlang::enexpr(vname)))
if( length(slct_v) > 1){slct_v[[1]] <- NULL }

return( dplyr::select(dplyr::group_by(dta , !!!grp_v) , !!!slct_v))
} #func

#つかってるのはpanelrパッケージのWageData
wg1 <- test_fun(WageData , list(wks , fem , lwage), union , occ )

# wg1
# # A tibble: 4,165 x 5
# # Groups:   union, occ [4]
# union   occ   wks   fem lwage
# <dbl> <dbl> <dbl> <dbl> <dbl>
#   1     0     0    32     0  5.56
# 2     0     0    43     0  5.72

途中listの要素数が1を超えてる場合に、1<- NULLしてるのは、要素が2つ以上ある場合ひとつめに余分な要素*2が入ってしまうからである。
とりあえず、as.list(rlange::enexpr() )でexpressionのlist化ができることがわかった。

めでたし、めでたし。


【MV】バックドロップシンデレラ/さらば青春のパンク【11/2ベストアルバム発売】


Enjoy!!

*1:もっと日本のR界隈頑張れって思ったけど頑張ってる人は英語で発信してるんだろう

*2:list()ってやつ