【问题标题】:Guidance in using rpy2 eval expression使用 rpy2 eval 表达式的指导
【发布时间】:2011-10-25 11:01:30
【问题描述】:

我对 R 和 rpy2 都是新手。我正在尝试移植以下示例

library(MASS)  # for eqscplot  
data(topo, package="MASS")  
topo.kr <- surf.ls(2, topo)  
trsurf <- trmat(topo.kr, 0, 6.5, 0, 6.5, 50)  

到 rpy2。

到现在为止

import  rpy2.robjects as robjects
robjects.r('library(spatial)')  
f1 = robjects.r['surf.ls']  
x = robjects.IntVector([1,2,3])  
y = robjects.IntVector([1,2,3])  
z = robjects.IntVector([1,30,3])  
res = f1(2, x,y,z)  

我假设结果应该是res。但是,当我使用 print(res.r_repr()) 打印 res 时,我得到一个无法评估的表达式。 非常感谢您对此的任何帮助。

【问题讨论】:

  • 我不清楚什么是“无法评估”。此外,您的 rpy2 代码与您的 R 代码不对应(对 surf.ls() 的调用没有相同的参数)。
  • 另外,你到底为什么要同时加载 rpy 和 rpy2? from rpy2 import robjects 应该足够了,然后使用 robjects.rrobjects.IntVector
  • “无法评估”意味着当我发出“print res1.r_repr()”时,我没有返回值数组。相反, res1 包含一个 r 表达式。我的猜测是,为了获得实际值,我需要发出一个命令来评估表达式。
  • 到目前为止,我不确定是否担心实际参数,因为该函数执行某些操作并返回结果。 @Brandon:感谢您指出我已修复它。
  • @Sandeep:调用 print() 的副作用是将文本打印到控制台;如果它返回一组值,我会感到不安。调用 f1() 的结果是 res1,而你的意思对我来说仍然是个谜(除了调用 print() 或 'res' 而不是 'res1')。

标签: python r rpy2 cran


【解决方案1】:

然后问题更多:如何将 R 列表转换为 Python 字典(与评估表达式无关)。 使用 rpy2-2.2.x(和 2.3-dev):

from rpy2.robjects.vectors import ListVector
# make an R list
l = ListVector({'a': 1, 'b': 'b'})

# get a Python dict out of an R list
dict(l.iteritems())

【讨论】:

  • 它确实适用于我的 2.1.9 安装。唯一的问题是它不会将值(如果它们是 IntVectors 或 FloatVectors)转换为 python 类型。像 dict([(i,[k for k in j]) for i, j in res.iteritems()]) 之类的东西可以解开它,但这越来越厚了。
  • @Mark:不仅厚;它只会处理一层嵌套。你可以有一个 R 列表的 R 列表 ...(你明白了),并且转换可能被编码为最短的递归。如果您只关心将长度为 1 的向量转换为 Python 标量,那么只需在转换规则中指定它(参见 rpy.sourceforge.net/rpy2/doc-2.2/html/…
【解决方案2】:

您的代码运行良好。我认为您只是无法访问结果。您生成的“res”对象本质上是一个 R 列表。我会把它转换成对应的 Python 字典。

rListObj = {}
for key,val in zip(robjects.r.names(res),res):
  rListObj[key] = [i for i in val] #R Vector to List

结果:

{'f': [1.0, 1.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0], 'rx': [1, 3], 'ry': [1, 3], 'np': [2], 'beta': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 'r': [-1.7320508075688772, -1.6729239521451333e-16, -1.4142135623730951, -1.1547005383792512, -5.187907395343139e-17, -0.8164965809277259, -1.6729239521451333e-16, -1.4142135623730951, 3.415236843329339e-17, nan, -1.1547005383792512, -5.187907395343139e-17, -0.8164965809277259, nan, 0.0, -1.1547005383792512, -5.187907395343139e-17, -0.8164965809277259, nan, 0.0, 0.0], 'call': [<SignatureTranslatedFunction - Python:0xb7539dec / R:0xa686cec>, <IntVector - Python:0xb7534cac / R:0xa69e788>, <IntVector - Python:0xb7534d2c / R:0xa5f72f8>, <IntVector - Python:0xb7534c2c / R:0xa5f7320>, <IntVector - Python:0xb7534bac / R:0xa5f7348>], 'y': [1, 2, 3], 'x': [1, 2, 3], 'z': [1, 30, 3], 'wz': [0.0, 0.0, 0.0]}

我在 rpy2 (2.1.9) 的较旧版本上对此进行了测试,使用更新的版本可能有更时髦的方法。

【讨论】:

  • 谢谢马克。这就是我所缺少的。
  • @Mark:有更简单的方法可以做到这一点(用 2.2.x 和 2.3-dev 测试;它/可能/适用于 2.1.x 系列)。见下文
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多