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 

理想情况下,我会得到这个与summarize一起工作,就像在示例答案中所做的那样,进行多次计算/标记输出,但我也无法让它工作,而且在语法方面真的变得很尴尬:

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 方法,但我不知道如何使用它们,因为文档和示例很难找到。

任何帮助是极大的赞赏。谢谢。

编辑

lgautier 用 nrow 而非长度修复 myfunc 的解决方案。

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

ggplot2 的解决方案如果对其他人有用(注意必须将 x 和 y 值添加到 mms_cor 作为使用 aes_string 的解决方法(无法让 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 可以做的意想不到的事情之一(注意:代码未经测试,可能存在拼写错误):

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 回答