在R中通过system命令执行Python脚本后直接获取Dataframe
在R中直接获取Python生成的DataFrame(无需保存文件)
不用再绕弯子存CSV啦!推荐用reticulate包来实现R和Python的无缝交互——这是RStudio官方推出的工具,专门用来在R里调用Python代码、共享对象,比用system命令高效太多了。下面分两种方案给你演示:
方案一:用reticulate直接调用Python函数(最推荐)
这个方法能让你在R里直接运行Python代码、调用函数,还能直接把Python的DataFrame转换成R的data.frame,完全不用中间文件。
步骤1:安装并加载reticulate
install.packages("reticulate") library(reticulate)
步骤2:指定你的Python环境
告诉reticulate用你的Anaconda Python路径:
use_python("/Users/ravinderbhatia/anaconda/bin/python")
步骤3:在R中调用你的Python函数
你有两种方式:
- 把Python代码直接嵌入R里
- 导入外部的Python脚本
这里我们用导入外部脚本的方式:
# 导入你的Python脚本 source_python("/Users/ravinderbhatia/Downloads/Untitled3.py") # 直接调用Python里的get_similar_CRs函数,参数和之前一致 result_df <- get_similar_CRs("EMEA", "regulatory", "10% productivity saves SOW") # 现在result_df就是R的data.frame了! print(result_df)
注意:修改你的Python脚本
你需要稍微调整一下Python脚本,去掉那些额外的print语句(不然会在R控制台输出无关内容),确保函数正确返回DataFrame即可:
import pandas as pd import numpy as np from difflib import SequenceMatcher def similar(a, b): return SequenceMatcher(None, a, b).ratio() def get_similar_CRs(arg1, arg2, arg3): ## 创建模拟数据 cr_id=range(1,41) description=['change in design','More robust system required', 'Grant system adminstrator rights', 'grant access to all products', 'Increase the credit limit', 'EDAP Scenario', 'Volume prpductivity for NA 2015', '5% productivity saves SOW', 'effort reduction', 'reduction of false claims', 'Volume productivity EMEA', 'Volume productivity for NA 2016', '10% productivity saves SOW', ] region=['EMEA','Asia Pacific','UK'] business=['card','secured loan','mortgage'] type=['regulatory','system','audit'] status=['pending','approved'] data=pd.DataFrame() data['description']=np.random.choice(description, 40) data['cr_id']=cr_id data['region']=np.random.choice(region,40) data['business']=np.random.choice(business, 40) data['status']=np.random.choice(status,40) data['type']=np.random.choice(type,40) subset_data=data.loc[data.region == arg1] subset_data=subset_data.loc[subset_data.type ==arg2] new_cr=arg3 cr_list=data['description'].unique().tolist() similar_CR=[] for cr in cr_list: result=similar(new_cr,cr) if result >=0.8: similar_CR.append(cr) temp=subset_data.loc[subset_data.description.isin(similar_CR)] temp=temp[['description','status','region']] return temp # 移除原来的print(temp),reticulate会直接把返回的DataFrame传给R
方案二:通过JSON传递(不用reticulate的备选)
如果你暂时不想用reticulate,可以让Python把DataFrame转成JSON输出到标准输出,然后R捕获这个输出再解析成data.frame。
修改Python脚本
在脚本最后,把DataFrame转成JSON输出:
# 原有代码不变,最后替换print(temp)为: print(temp.to_json(orient="records"))
R端捕获输出并解析
用system的intern=TRUE参数捕获Python的输出,然后用jsonlite包解析:
install.packages("jsonlite") library(jsonlite) # 捕获Python脚本的输出 json_output <- system("/Users/ravinderbhatia/anaconda/bin/python /Users/ravinderbhatia/Downloads/Untitled3.py EMEA regulatory '10% productivity saves SOW'", intern=TRUE) # 解析成R的data.frame result_df <- fromJSON(paste(json_output, collapse="")) print(result_df)
这个方法虽然可行,但不如reticulate灵活——比如你没办法在R里调用Python的其他函数,也不能共享变量,所以还是优先推荐方案一。
内容的提问来源于stack exchange,提问作者user2906657
相关产品推荐
相关产品推荐

