2

学習演習として、また自分のデータで似たようなことをしたいので、この例の答えを正確にコピーして、rpy2 経由で Python に実装しようとしています。

plyr は便利な構文 (as.quoted 変数、summary、関数など) を多く使用しているため、rpy2 に簡単に移植することはできませんでした。ggplot2 セグメントに到達しなくても、**{} を使用して「.」引数:

# import rpy2.robjects as ro
# from rpy2.robjects.packages import importr
# stats= importr('stats')
# plyr = importr('plyr')
# bs = importr('base')
# r = ro.r
# df = ro.DataFrame

mms = df( {'delicious': stats.rnorm(100), 
           'type':bs.sample(bs.as_factor(ro.StrVector(['peanut','regular'])), 100, replace=True),
           'color':bs.sample(bs.as_factor(ro.StrVector(['r','g','y','b'])), 100, replace=True)} )

# first define a function, then use it in ddply call
myfunc  = r('''myfunc <- function(var) {paste('n =', length(var))} ''')
mms_cor = plyr.ddply(**{'.data':mms, 
                        '.variables':ro.StrVector(['type','color']), 
                        '.fun':myfunc})

これはエラーなしで実行されますが、結果の mms_cor を出力すると次のようになります。これは、関数が ddply 呼び出しのコンテキストで正しく機能していないことを示唆しています (mms data.frame の長さは 3 であり、これが計算されていると思います)。 myfunc への他の入力が異なる値を返すため):

     type color    V1
1  peanut     b n = 3
2  peanut     g n = 3
3  peanut     r n = 3
4  peanut     y n = 3
5 regular     b n = 3
6 regular     g n = 3
7 regular     r n = 3
8 regular     y n = 3 

理想的には、回答例で行ったように、これを要約して機能させて、複数の計算/出力にラベルを付けることができますが、これも機能させることができず、構文的に厄介になります:

mms_cor = plyr.ddply(plyr.summarize, n=bs.paste('n =', bs.length('delicious')), 
                     **{'.data':mms,'.variables':ro.StrVector(['type','color'])})

これにより、「n = 1」で上記と同じ出力が得られます。1項目のベクトル「おいしい」の長さを反映していることは知っていますが、これを文字列ではなく変数にする方法、またはそれがどの変数になるかわかりません(これが、上記の関数に移動した理由です) . さらに、as.quoted 変数構文 (例: ddply(.data=mms, .(type, color) , ...) ) を rpy2 で使用する方法を知っておくと便利です。plyr にはいくつかの as_quoted メソッドがあることは知っていますが、ドキュメントと例を見つけるのが難しいため、それらの使用方法がわかりません。

どんな助けでも大歓迎です。ありがとう。

編集

長さではなくnrowでmyfuncを修正するlgautierのソリューション。

myfunc = r('''myfunc <- function(var) {paste('n =', nrow(var))} ''')

他の人に役立つ場合の ggplot2 の解決策(aes_string を使用するための回避策として x と y の値を mms_cor に追加する必要があることに注意してください (aes を Python 環境で動作させることはできません) :

#rggplot2 = importr('ggplot2') # note ggplot2 import above doesn't take 'mapping' kwarg
p = rggplot2.ggplot(data=mms, mapping=rggplot2.aes_string(x='delicious')) + \
    rggplot2.geom_density() + \
    rggplot2.facet_grid('type ~ color') + \
    rggplot2.geom_text(data=mms_cor, mapping=rggplot2.aes_string(x='x', y='y', label='V1'), colour='black', inherit_aes=False)

p.plot()
4

1 に答える 1

2

コールバックを使用しているため、rpy2 で実行できる予期しないことの 1 つを示すことに抵抗できません (注: コードはテストされていないため、タイプミスがある可能性があります)。

def myfunc(var):
    # var is a data.frame, the length of
    # the first vector is the number of rows
    if len(var) == 0:
        nr = 0
    else:
        nr = len(var[0])
    # any string format feature in Python could
    # be used here
    return 'n = %i' % nr 

# create R function from the Python function
from rpy2.rinterface import rternalize
myfunc_r = rternalize(myfunc)

mms_cor = plyr.ddply(**{'.data':mms, 
                        '.variables':ro.StrVector(['type','color']), 
                        '.fun':myfunc_r})
于 2013-01-08T21:03:52.077 に答える