やりたいこと
rpy2やpyperでPythonからRを呼び出せることは知っていた。しかし,Pythonで整形したデータフレームをRが読み込んでRStudio上などで解析するやり方が探せなかったので,以下にやり方を残しておく。
やり方
確認した実行環境
- Python 3.9.0
- R 4.1.1
- pandas 1.2.5
- PypeR 1.1.2
converter.py}
import pyper
import pandas as pd
from pathlib import Path, PosixPath
from typing import Union
def save_rds(df: pd.core.frame.DataFrame, file: Union[str, PosixPath]) -> bool:
strfile = str(file)
pathfile = Path(file)
# datetime型があると変換エラーが起こるのでstrにする
df = pd.concat([df.select_dtypes('datetime').astype(str), df.select_dtypes(exclude='datetime')], axis=1)
# PosixPathがあると変換エラーが起こるのでstrにする
df = pd.concat([df.select_dtypes('object').astype(str), df.select_dtypes(exclude='object')], axis=1)
r = pyper.R(use_pandas='True')
r.assign("df", df)
r(f'saveRDS(df, file="{strfile}")')
ret = r.get(f'readRDS("{strfile}")')
if ret is None:
print('Conversion failed')
pathfile.unlink()
return False
else:
return True
解説
なんということはなく,pyperなどでデータフレームをR側に渡して,saveRDS()
でシリアライズしているだけである。
自分がつまづいた点としては,
- Pandasにdatetime型があると変換に失敗する
- Pandasのobject型の中にPosixPathがあると変換に失敗する (自分はファイルの解析をする際にパス情報としてよく入れている)
- 日本語が入っていると変換に失敗する
があり,1, 2の対策は関数の中に実装した。他にもいろいろあると思うのでsaveRDS()
の後にreadRDS()
でバリデーションしている。Conversion failedが出たら適宜対策を入れてほしい。
あとはR側でreadRDS()
してもらえればよい。余談ではあるが,str
に変換したdatetime
はR側ではas.Posixlt()
すれば時間として扱うことができる。
以上