Python rpy2/dataframe访问中的命名列表等效项
我试图用两种不同的方式从R中的包复制一个例子,从rpy2复制。在第一个例子中,我只是使用Python rpy2/dataframe访问中的命名列表等效项,python,r,pandas,rpy2,Python,R,Pandas,Rpy2,我试图用两种不同的方式从R中的包复制一个例子,从rpy2复制。在第一个例子中,我只是使用robjects.r和一个字符串来精确复制和粘贴r代码: import rpy2.robjects as robjects import rpy2.robjects.numpy2ri import rpy2.robjects.pandas2ri import rpy2.robjects.packages as rpackages robjects.pandas2ri.activate() mnp = rpa
robjects.r
和一个字符串来精确复制和粘贴r代码:
import rpy2.robjects as robjects
import rpy2.robjects.numpy2ri
import rpy2.robjects.pandas2ri
import rpy2.robjects.packages as rpackages
robjects.pandas2ri.activate()
mnp = rpackages.importr('MNP')
base = rpackages.importr('base')
r = robjects.r
r.data('detergent')
rcmd = '''\
mnp(choice ~ 1, choiceX = list(Surf=SurfPrice, Tide=TidePrice,
Wisk=WiskPrice, EraPlus=EraPlusPrice,
Solo=SoloPrice, All=AllPrice),
cXnames = "price", data = detergent, n.draws = 500, burnin = 100,
thin = 3, verbose = TRUE)'''
res = r(rcmd)
这很好,并且重现了我可以直接在R中执行的操作。我还想尝试使用python可访问对象运行此代码,从数据帧传入数据:
import rpy2.rlike.container as rlc
df = robjects.pandas2ri.ri2py(r['detergent'])
choiceX = rlc.TaggedList(['SurfPrice', 'TidePrice', 'WiskPrice', 'EraPlusPrice', 'SoloPrice', 'AllPrice'],
tags=('Surf', 'Tide', 'Wisk', 'EraPlus', 'Solo', 'All'))
res = mnp.mnp('choice ~ 1',
choiceX=['SurfPrice', 'TidePrice', 'WiskPrice', 'EraPlusPrice', 'SoloPrice', 'AllPrice'],
cXnames='price',
data=df, n_draws=500, burnin=100,
thin=3, verbose=True)
此操作失败,错误如下:
Error in xmatrix.mnp(formula, data = eval.parent(data), choiceX = call$choiceX, :
Error: Invalid input for `choiceX.'
You must specify the choice-specific varaibles at least for all non-base categories.
另一个例子建议用rpy2标记列表替换R命名列表。如果我删除MNP的choiceX
和cXnames
参数(它们是可选的),代码将运行,因此看起来pandas数据帧传递正确
我不确定TaggedList在进入R后是否被正确解释为命名列表,或者MNP是否存在将choiceX
的内容与pandas数据帧关联的问题
有人知道这里发生了什么吗
更新
根据@lgautier的建议,我将代码修改为:
choiceX = rlc.TaggedList([base.as_symbol('SurfPrice'), base.as_symbol('TidePrice'),
base.as_symbol('WiskPrice'), base.as_symbol('EraPlusPrice'),
base.as_symbol('SoloPrice'), base.as_symbol('AllPrice')],
tags=('Surf', 'Tide', 'Wisk', 'EraPlus', 'Solo', 'All'))
res = mnp.mnp(robjects.Formula('choice ~ 1'),
choiceX=choiceX,
cXnames='price',
data=df, n_draws=500, burnin=100,
thin=3, verbose=True)
然而,我得到了一个与之前发布的相同的错误
更新2
按照@lgautier建议的解决方案,以下代码:
choiceX = rlc.TaggedList([base.as_symbol('SurfPrice'),
base.as_symbol('TidePrice'),
base.as_symbol('WiskPrice'),
base.as_symbol('EraPlusPrice'),
base.as_symbol('SoloPrice'),
base.as_symbol('AllPrice')],
tags=('Surf', 'Tide', 'Wisk',
'EraPlus', 'Solo', 'All'))
choiceX = robjects.conversion.py2ro(choiceX)
# add the names
choiceX.names = robjects.vectors.StrVector(('Surf', 'Tide',
'Wisk', 'EraPlus',
'Solo', 'All'))
res = mnp.mnp(robjects.Formula('choice ~ 1'),
choiceX=choiceX,
cXnames='price',
data=df, n_draws=500, burnin=100,
thin=3, verbose=True)
仍然会产生错误(尽管是不同的错误):
as.vector(x,模式)中的错误:
无法将类型“symbol”强制为类型“any”的向量
---------------------------------------------------------------------------
RRontimeError回溯(最近一次呼叫上次)
在()
3“价格”,
4数据=df,n_图纸=500,磨合=100,
---->5瘦=3,详细=真)
/Users/lev/anaconda/envs/rmnptest/lib/python2.7/site-packages/rpy2-2.5.6-py2.7-macosx-10.5-x8664.egg/rpy2/robjects/functions.pyc in_uuucall_uu(self,*args,**kwargs)
168 v=kwargs.pop(k)
169夸尔格[r_k]=v
-->170返回超级(SignatureTranslatedFunction,self)。\调用(*args,**kwargs)
171
172模式\u link=re.compile(r'\\link\{(+?)\})
/Users/lev/anaconda/envs/rmnptest/lib/python2.7/site-packages/rpy2-2.5.6-py2.7-macosx-10.5-x8664.egg/rpy2/robjects/functions.pyc in_uuucall_uu(self,*args,**kwargs)
kwargs.items()中的k、v为98:
99 new_kwargs[k]=转换.py2ri(v)
-->100 res=super(函数,自身)。\调用(*新参数,**新参数)
101 res=转换。ri2ro(res)
102返回res
RRuntimeError:as.vector(x,模式)中的错误:
无法将类型“symbol”强制为类型“any”的向量
Python代码与您的R不对应。您在发帖时就发现了这一点,所以下面有详细信息。总结是R符号和Python字符串不是等价的(尽管R在某些地方同时允许使用这两种符号会让它自己的用户感到困惑,例如,library(“MNP”)
和library(MNP)
都可以使用)
这与这个问题没有什么不同:
…除了choiceX
将是一个未赋值的R表达式,而不仅仅是一个符号
R代码为:
您拥有的Python是(关于差异的注释):
choiceX=rlc.TaggedList(['SurfPrice'、'TidePrice'、'WiskPrice',
“EraPlusPrice”、“SoloPrice”、“AllPrice”],
标签=('Surf'、'Tide'、'Wisk',
‘EraPlus’、‘Solo’、‘All’)
#^-这是一个“标记列表”,R等效值为
#列表(Surf=“SurfPrice”、Tide=“TidePrice”、Wisk=“WiskPrice”,
#EraPlus=“EraPlusPrice”,Solo=“SoloPrice”,All=“AllPrice”)
#与上述R代码更接近的是:
#rlc.TaggedList([as_symbol('surffrice')、as_symbol('TidePrice'),
# ...
#标签=(‘冲浪’、‘潮汐’、…)
res=mnp.mnp('choice~1',
#^-这是一个字符串。若要使其成为R公式,请执行以下操作
#robjects.公式('choice~1')
choiceX=['SurfPrice'、'TidePrice'、'WiskPrice',
“EraPlusPrice”、“SoloPrice”、“AllPrice”],
#^-我想这应该是上面定义的choiceX
cxname='price',
#^-这是一个字符串,如R中所示
数据=df,
n_=500,burnin=100,
精简=3,详细=真)
编辑:
这意味着下面的方法应该有效
choiceX=robjects.rinterface.parse(“”)
列表(冲浪=冲浪价格,潮汐=潮汐价格,
Wisk=WiskPrice,EraPlus=EraPlusPrice,
Solo=SoloPrice,All=AllPrice)“”)
目前,rpy2
没有提供许多用于构造R表达式的实用程序。如果变量名是Python级别的参数
你可以考虑这样的事情:
rcode = 'list('+''.join('%s=%s' % (k,v) \
for k,v in \
(('Surf','SurfPrice'),
('Tide', 'TidePrice'),
('Wisk','WiskPrice'),
('EraPlus','EraPlusPrice'),
('Solo','SoloPrice'),
('All','AllPrice'))) + ')'
choiceX = robjects.rinterface.parse(rcode)
谢谢你的建议。正如上面的更新所指出的,我相信我复制了你的建议,但是得到了一个相同的错误。我仍然遗漏了什么吗?谢谢你研究这个问题。第一个解决方法仍然是给出一个错误。请参阅我原始帖子中的更新2。@JoshAdel。啊,是的……choiceX应该是一个未计算的R表达式。The第一种解决方法不起作用。
data(detergent)
mnp(choice ~ 1,
# ^- this is a "formula", which is an expression in R
choiceX = list(Surf=SurfPrice, Tide=TidePrice,
Wisk=WiskPrice, EraPlus=EraPlusPrice,
Solo=SoloPrice, All=AllPrice),
# ^- this is a list of objects, but with the cautionary note
# that R evaluates expressions in argument lazily. Therefore
# the safest is to have it as an R expression (it may or may
# not work if evaluated, but this depends on the code in
# `mnp`)
cXnames = "price",
# ^- this is a string
data = detergent,
n.draws = 500, burnin = 100,
thin = 3, verbose = TRUE)
rcode = 'list('+''.join('%s=%s' % (k,v) \
for k,v in \
(('Surf','SurfPrice'),
('Tide', 'TidePrice'),
('Wisk','WiskPrice'),
('EraPlus','EraPlusPrice'),
('Solo','SoloPrice'),
('All','AllPrice'))) + ')'
choiceX = robjects.rinterface.parse(rcode)