使用rpy2-2.0.7 + python 2.6 + r 2.11在windows 7上的ggplot2问题

3 投票
3 回答
2348 浏览
提问于 2025-04-16 02:59

我正在使用 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 个回答

1

当你需要绘制更复杂的图表时,这里有一些小技巧可以让事情变得简单一些:

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()
2

在你关闭 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']()
3

我使用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")'。这样,我每次会话中只会看到一次警告。)

撰写回答