2016-06-27 5 views
0

最初にオフになりました。これまでに尋ねられた場合、私は見て、私がしようとしているものに一致するものを見つけることができませんでした。突然変異体内の関数に引数を動的に提供

私は、データフレームのユーザー生成の列に従ってデータを格納する関数を作成しようとしています。これを行うには、基数Rからのdplyrとcut()のmutate()関数を使用しています。しかし、cut()関数の中で関数を通過する列名の使い方を理解できません。突然変異体の中に現れる)。

thisthisを数時間過ごしましたが、それでもわかりません。私の理解では、以下のコードのfoo()、bar()および最後の行は、すべて同じ出力を生成する必要があります。しかし、関数には2つのエラーがあり、関数にラップされていないものだけがハードコーディングされた列名を使用しています。

ここでは何が起こっていますか?なぜfoo()はbar()とは異なる出力を生成するのですか?そして、関数の正しい振る舞いを可能にするためにlazyevalを正しく使うにはどうすればいいですか?

library(dplyr) 
library(lazyeval) 

foo <- function(data, col, bins){ 
    by = lazyeval::interp(quote(x), x = as.name(col)) 
    print(paste0("typeof(by): ", typeof(by))) 
    print(paste0(" by: ", by)) 

    df <- data %>% 
     dplyr::mutate(bins = cut(by, 
     breaks = bins, 
     dig.lab = 5, 
     include.lowest = T)) 
    df 
} 

bar <- function(data, col, bins){ 
    df <- data %>% 
    dplyr::mutate(bins = cut(lazyeval::interp(quote(x), x = as.name(col)), 
     breaks = bins, 
     dig.lab = 5, 
     include.lowest = T)) 
    df 
} 

#produce sample data and bins list 
df <- expand.grid(temp=0:8,precip=seq(0.7,1.3,by=0.1)) 
df$rel <- seq(40,100,length=63) 
bins <- seq(40,100,by=10) 

foo(df,"rel",bins) # produces "Error: 'rel' not found" 
bar(df,"rel",bins) # produces "Error: 'x' must be numeric" 

# but this works 
dplyr::mutate(df, bins = cut(rel, breaks = bins, dig.lab = 5, include.lowest = T)) 
+1

を= 5、include.lower = TRUE)、x = as.name(col))) 'のようになります。 – aosmith

+0

それは動作します!私はここで一瞬で答えを掲示します。 – tbadams45

+0

@aosmithこれ以上のことを考えて、私はそれがなぜ機能するのか理解するのに苦労しています。 interp()はカット前に実行されていたようですが、前回のコーディング経験では関数が内部から実行されることを教えています。 – tbadams45

答えて

1

解説は、mutate_(bins = interp(~cut(x, bins, dig.lab = 5, include.lowest = TRUE), x = as.name(col)))を使用することです。 mutateの代わりにmutate_を使用すると、標準的な評価を使用することができます。

interpmutate_の外に呼び出すと、interpcutの状況を確認するのが最も簡単です。 (それは同じいずれかの方法を実行します。)col == "rel"を想定すると、

call = interp(~cut(x, bins, dig.lab = 5, include.lowest = TRUE), x = as.name(col))) 

はのmutateにこの表現を挿入

~cut(rel, bins, dig.lab = 5, include.lowest = TRUE) 

を与える私たちは、正確にhereを提供する例に従うことができます。

muatate_(bins = call) 

正しい結果が得られます。

また、ユーザーが「ビン」に置き換え、列名を提供する可能性があります:私はおそらく `mutate_(ビン= interpの(〜カット(X、ビン、dig.labのようなものを持っているでしょう

dplyr::mutate_(.dots = setNames(call, c(binName))) 
関連する問題