作为一个学习练习,因为我想对自己的数据做类似的事情,所以我试图完全复制这个例子的答案,但通过 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()