使用Rpy2将Pandas DataFrame转换为R dataframe

11 投票
2 回答
9937 浏览
提问于 2025-04-17 21:47

我有一个 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 个回答

9

很棒的回答 @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)
3

很遗憾,这个过程会有点困难,因为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....

这个例子摘自这里这里

撰写回答