使用rpy2-2.0.7 + python 2.6 + r 2.11在windows 7上的ggplot2问题
我正在使用 rpy2-2.0.7 这个版本(因为我需要在 Windows 7 上使用,而更新的 rpy2 版本编译起来太麻烦了),想把一个有两列的数据框传到 R 里,创建一些 ggplot2 的图层,然后把图像输出成一个 <.png> 文件。
我花了无数个小时在语法上纠结;有一次我确实成功输出了需要的文件,但(真是傻)没注意到,然后继续在代码上纠结……
我非常希望能得到一些帮助;下面是一个(简单的)示例来演示。非常感谢你的帮助!!! ~ Eric Butter
import rpy2.robjects as rob
from rpy2.robjects import r
import rpy2.rlike.container as rlc
from array import array
r.library("grDevices") # import r graphics package with rpy2
r.library("lattice")
r.library("ggplot2")
r.library("reshape")
picpath = 'foo.png'
d1 = ["cat","dog","mouse"]
d2 = array('f',[1.0,2.0,3.0])
nums = rob.RVector(d2)
name = rob.StrVector(d1)
tl = rlc.TaggedList([nums, name], tags = ('nums', 'name'))
dataf = rob.RDataFrame(tl)
## r['png'](file=picpath, width=300, height=300)
## r['ggplot'](data=dataf)+r['aes_string'](x='nums')+r['geom_bar'](fill='name')+r['stat_bin'](binwidth=0.1)
r['ggplot'](data=dataf)
r['aes_string'](x='nums')
r['geom_bar'](fill='name')
r['stat_bin'](binwidth=0.1)
r['ggsave']()
## r['dev.off']()
*输出的图像只是一个空白的图片(181 b)。
在我玩弄 ggplot2 的时候,R 自己抛出了一些常见的错误:
r['png'](file=picpath, width=300, height=300)
r['ggplot']()
r['layer'](dataf, x=nums, fill=name, geom="bar")
r['geom_histogram']()
r['stat_bin'](binwidth=0.1)
r['ggsave'](file=picpath)
r['dev.off']()
*RRuntimeError: 错误:图中没有图层
r['png'](file=picpath, width=300, height=300)
r['ggplot'](data=dataf)
r['aes'](geom="bar")
r['geom_bar'](x=nums, fill=name)
r['stat_bin'](binwidth=0.1)
r['ggsave'](file=picpath)
r['dev.off']()
*RRuntimeError: 错误:在设置美学时,它们只能取一个值。问题:fill,x
3 个回答
当你需要绘制更复杂的图表时,这里有一些小技巧可以让事情变得简单一些:
from rpy2 import robjects
from rpy2.robjects.packages import importr
import rpy2.robjects.lib.ggplot2 as ggplot2
r = robjects.r
grdevices = importr('grDevices')
p = r('''
library(ggplot2)
p <- ggplot(diamonds, aes(clarity, fill=cut)) + geom_bar()
p <- p + opts(title = "{0}")
# add more R code if necessary e.g. p <- p + layer(..)
p'''.format("stackbar"))
# you can use format to transfer variables into R
# use var.r_repr() in case it involves a robject like a vector or data.frame
p.plot()
# grdevices.dev_off()
在你关闭 dev() 之前,必须先调用它,这意味着你需要先使用 print()(就像上面 JD 猜测的那样),然后再执行 dev.off()。
from rpy2 import robjects
r = robjects.r
r.library("ggplot2")
robjects.r('p = ggplot(diamonds, aes(clarity, fill=cut)) + geom_bar()')
r.ggsave('/stackBar.jpeg')
robjects.r('print(p)')
r['dev.off']()
我使用rpy2主要是通过Nathaniel Smith的一个很棒的小模块,叫做 rnumpy(你可以在rnumpy主页找到“API”链接)。使用这个模块,你可以做到:
from rnumpy import *
r.library("ggplot2")
picpath = 'foo.png'
name = ["cat","dog","mouse"]
nums = [1.0,2.0,3.0]
r["dataf"] = r.data_frame(name=name, nums=nums)
r("p <- ggplot(dataf, aes(name, nums, fill=name)) + geom_bar(stat='identity')")
r.ggsave(picpath)
(我对你想要的图表样式有点猜测,但大概意思就是这样。)
另一个很方便的功能是通过ipy_rnumpy模块从Python进入“R模式”。(你可以在rnumpy主页找到“IPython集成”链接。)
对于复杂的事情,我通常会先在R中试验,直到我搞清楚绘图命令为止。因为在rpy2或rnumpy中,错误报告有时候会变得很麻烦。
比如,有时候一个赋值(或者其他计算)的结果会被打印出来,即使它应该是隐形的。这在给大型数据框赋值时特别烦人。一个快速的解决办法是,在出问题的那一行末尾加上一个返回短小结果的语句。例如:
In [59] R> long <- 1:20
Out[59] R>
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
[19] 19 20
In [60] R> long <- 1:100; 0
Out[60] R> [1] 0
(为了消除rnumpy中一些重复出现的警告,我编辑了rnumpy.py,添加了'from warnings import warn',并把'print "error in process_revents: ignored"'替换成'warn("error in process_revents: ignored")'。这样,我每次会话中只会看到一次警告。)