2017-05-30 1 views
2

目的は、ユーザ定義関数の(オプションの)引数として「サブセット式」(論理ベクトルではない)を使用し、それを使ってデータフレームのサブセット。`subset()`を関数内で動作させる

x <- data.frame(a=1, b=gl(2,5)) 

f <- function(data, subset) { 
    if (!missing(subset)) 
     data <- subset(data, subset) 
    data 
} 

上記のコードは動作しませんし、どちらもsubsetが供給されたときに、私はエラーを取得する両方のケースで

f <- function(data, subset) { 
    if (!missing(subset)) 
     data <- data[with(data, subset), ] 
    data 
} 

を行います。

> f(x, b == 2) 
Error in f(x, b == 2) (from frame.r!322341dM#2) : object 'b' not found 

所望の出力:

> f(x) 
    a b 
1 1 1 
2 1 1 
3 1 1 
4 1 1 
5 1 1 
6 1 2 
7 1 2 
8 1 2 
9 1 2 
10 1 2 
> f(x, b == 2) 
    a b 
6 1 2 
7 1 2 
8 1 2 
9 1 2 
10 1 2 
+0

'x $ b == 2'が必要です。 – G5W

+0

bは変数ではなく、xの列なので、Rが理解できるように関数を入力する(または関数に貼り付ける)必要があります。 G5Wのように、または3つの属性、データフレーム、列名、値を取って関数に貼り付け、必要な出力を抽出する機能を設定することもできます。 – sconfluentus

答えて

4

この1つは仕事です。

f <- function(data, ss) { 
    if (!missing(ss)){ 
     e <- substitute(ss) 
     r <- eval(e, data, parent.frame()) 
     data <- subset(data, r) 
    } 
    data 
} 

# > f(x, b == 2) 
# a b 
# 6 1 2 
# 7 1 2 
# 8 1 2 
# 9 1 2 
# 10 1 2 

subsetと引数名ssを置き換える動作しません:あなたは、第二引数が式であることをfを伝える必要があります。なぜ私は分からない。実際には、私はsubset.data.frameのソースコードをナビゲートして考え出しました。

+0

@ G.Grothendieck編集。私はこれを "サブセット"のソースで見ましたが、それが何をしているのかはわかりません。これを説明してくれてありがとう。 – mt1022

1

あなたの機能は基本的にsubset()と同じシグネチャを持っているので、直接パラメータメーターをsubset()に渡すこともできます。あなたはこの関数にsubset()機能とは異なるパラメータ名を与えたので

f <- function(data, ss) { 
    if (!missing(ss)){ 
     call <- unname(match.call()) 
     call[[1]] <- quote(subset) 
     data <- eval(call, parent.frame()) 
    } 
    data 
} 

unname()はここでは必要です。しかし基本的には、subset()への呼び出しであなたの関数に呼び出しをスワップします。これは、適切な文脈でフィルタを評価する「汚い作業」を行う必要がないことを意味します。

関連する問題