rpy2调用sidrar包时报py2rpy不支持pandas DataFrame转换错误
场景说明
通过Python的rpy2库调用R生态的sidrar包获取Sidra平台数据,未使用sidrapy、DadosAbertosBrasil等Python原生工具包,原因是需要基于存储在Data.txt中的Sidra API地址批量生成CSV文件,sidrar包更适配该场景。
初始实现代码
import pandas as pd import numpy as np import rpy2.robjects.packages as rp from rpy2 import robjects as ro utils = rp.importr('utils') utils.chooseCRANmirror(ind=1) utils.install_packages("sidrar") sidrar = rp.importr("sidrar") table_NameUrl = pd.read_csv("Data.txt", sep=";", header= None) table_Size = len(table_NameUrl) sequence = np.arange(1, table_Size, 2) for i in sequence: csvName = table_NameUrl.iloc[::2] csvUrl = table_NameUrl.iloc[1::2] last_url = "/n3/all/n6/in%20n3%2028" fileName = (tableName + ".csv") url = (csvUrl + last_url) ro.globalenv['fileName'] = fileName ro.globalenv['url'] = url ro.r('table= get_sidra(api= url)') ro.r('write.csv(table, file= fileName, row.names = F)')
Data.txt文件格式
文件逐行存储文件名和对应API前缀,示例内容如下:
Panu 2.1.1, 2.1.5
/t/2093/p/2000,2010/v/93/c86/2776,2777,2778,2779,2780,2781/c2/0,4,5/c1/1,2/
Panu 5.1.1, 5.1.2, 5.1.3, 5.1.4, 5.1.5, 5.1.6, 5.1.7, 5.1.9, 5.1.10
/t/1612/p/2013,2014,2015,2016,2017/v/109,216,214/c81/2688,2691,2692,2694,2696,2708,2702,2715,2703/
Panu 5.1.8
/t/839/p/2013,2014,2015,2016,2017/v/109,216,214/c81/114254/
补充说明:last_url是Sidra API的地址补全后缀,需要和从文件读取的前缀拼接才能生成完整的有效请求地址。
报错信息
将拼接生成的CSV文件名fileName和请求地址url传入R全局环境时触发如下报错:
Conversion 'py2rpy' not defined for objects of type '<class 'pandas.core.frame.DataFrame'>'
原因
初始代码中通过iloc切片取到的csvName、csvUrl均为Pandas DataFrame类型对象,rpy2默认不支持该类型到R对象的自动转换,因此触发转换失败。
解决方案
引入rpy2的本地转换器,显式完成Pandas对象到R对象的转换即可解决该问题,需要新增的代码逻辑如下:
# 需提前导入pandas2ri模块,对应代码中的pr别名 from rpy2.robjects import pandas2ri as pr from rpy2.robjects.conversion import localconverter as lc with lc(ro.default_converter + pr.converter): fileName_c = ro.conversion.py2rpy(fileName) url_c = ro.conversion.py2rpy(url) ro.globalenv['fileName'] = fileName_c ro.globalenv['url'] = url_c
内容的提问来源于stack exchange,提问作者Thiago Santana

