python - 将 plyr (ddply) 与 rpy2 语法结合使用

标签 python r plyr rpy2

作为一项学习练习,并且因为我想对自己的数据执行类似的操作,所以我尝试将答案复制到 this example 完全一样,但通过 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 

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

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

这给出了与上面“n = 1”相同的输出。我知道它反射(reflect)了 1 项向量“delicious”的长度,但无法弄清楚如何使其成为变量而不是字符串,或者它会是哪个变量(这就是我转向上面的函数的原因) 。此外,了解如何获得 as.quoted 变量语法(例如 ddply(.data=mms, .(type, color), ...)) 与 rpy2 一起使用。我知道 plyr 有几个 as_quoted 方法,但我不知道如何使用它们,因为文档和示例很难找到。

非常感谢任何帮助。谢谢。

编辑:

lgautier 的解决方案,用 nrow 而不是 length 来修复 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()

最佳答案

由于您使用的是回调,所以我无法抗拒展示 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})

关于python - 将 plyr (ddply) 与 rpy2 语法结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14208437/

相关文章:

替换数据框中的特定行

r - R中治疗组和地点的多样性指数

r - 如何使用ddply按组对数据进行子采样?

如果至少有一个组成员满足条件,则从 data.frame 中删除组

python - 对 pandas 系列 `any` 、 `max` 、 `sum` 与 python 内置函数的性能好奇心

Python:按时间间隔对结果进行分组

Python 多处理似乎不使用多个内核

r - 如何在 R Shiny 中的同一行上创建带有超链接或其他元素的单行文本?

R:根据一个因素拆分数据,添加一个排名列并提取

python - 在 ZeroRPC 中实现自定义队列