使用Rpy2将Pandas DataFrame转换为R dataframe
我有一个 pandas 数据框(dataframe),我通过 pandas.rpy.common 中的 convert_to_r_dataframe 方法把它转换成 R 数据框。我是这样设置的:
self.event = pd.read_csv('C://' + self.event_var.get() + '.csv')
final_products = pd.DataFrame({'Product': self.event.Product, 'Size': self.event.Size, 'Order': self.event.Order})
r.assign('final_products', com.convert_to_r_dataframe(final_products))
r.assign('EventName', self.event_var.get())
r.assign('EventTime', self.eventtime_var.get())
r.source('application.r')
这里 self.event_var.get() 是从图形用户界面(GUI)中获取用户输入的(我正在用 Tkinter 创建一个应用程序)。Product、Size 和 Order 是 CSV 文件中的列。
因为 Rpy2 在 Python 中设置了 R 环境,所以我本以为最终的 final_products R 数据框会被 R 环境理解。不幸的是,虽然 R 脚本确实运行了,但结果却不正确(我用 R 脚本创建的图表在程序结束时都是空的)。不过,EventName 和 EventTime 变量是可以正常工作的。我是不是漏掉了什么?有没有人知道为什么在 Python 中分配的 R 数据框没有被 R 环境正确理解?
得到的错误信息:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1470, in __call__
return self.func(*args)
File "G:\Development\workspace\GUI\GUI.py", line 126, in evaluate
r.source('application.r')
File "C:\Python27\lib\site-packages\rpy2\robjects\functions.py", line 86, in __call__
return super(SignatureTranslatedFunction, self).__call__(*args, **kwargs)
File "C:\Python27\lib\site-packages\rpy2\robjects\functions.py", line 35, in __call__
res = super(Function, self).__call__(*new_args, **new_kwargs)
2 个回答
很棒的回答 @Mittenchops。因为 convert_to_r_dataframe 这个功能已经不再推荐使用了。所以上面的例子需要用 rpy2 接口来更新一下。
from rpy2.robjects import pandas2ri
pandas2ri.activate()
import pandas as pd
import numpy as np
from datetime import datetime
n = 10
df = pd.DataFrame({
"timestamp": [datetime.now() for t in range(n)],
"value": np.random.uniform(-1, 1, n)
})
r_dataframe = pandas2ri.py2ri(df)
print(r_dataframe)
很遗憾,这个过程会有点困难,因为Python转到R的过程比以前好多了,但仍然不完美,而且在Windows上现在还是挺麻烦的,看起来你正是在用Windows。
这有点像是个小技巧,但作为一个解决办法,你可以尝试在把pd.DataFrame赋值的时候先设置好名称和时间变量,然后再转换成R。
一旦数据到了R里,你就需要用R的函数来操作数据框,而不是用Python的函数——甚至你的获取器和设置器也得以一种更像这样的方式传入R环境:
myfunct = robjects.r('''
f <- function(r, verbose=FALSE) {
if (verbose) {
cat("I am calling f().\n")
}
2 * pi * r
}
f(3)
''')
来自这里。
不过,为了确认你的DataFrame是否正确转换,你可以先运行这个来调试一下:
import pandas as pd
import numpy as np
import pandas.rpy.common as com
from datetime import datetime
n = 10
df = pd.DataFrame({
"timestamp": [datetime.now() for t in range(n)],
"value": np.random.uniform(-1, 1, n)
})
r_dataframe = com.convert_to_r_dataframe(df)
print(r_dataframe)
看看输出的结果是不是像R打印数据框的那种样子,比如这样:
>>> timestamp value
0 2014-06-03 15:02:20 -0.36672....
1 2014-06-03 15:02:20 -0.89136....
2 2014-06-03 15:02:20 0.509215....
3 2014-06-03 15:02:20 0.862909....
4 2014-06-03 15:02:20 0.389879....
5 2014-06-03 15:02:20 -0.80607....
6 2014-06-03 15:02:20 -0.97116....
7 2014-06-03 15:02:20 0.376419....
8 2014-06-03 15:02:20 0.848243....
9 2014-06-03 15:02:20 0.446798....