Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2@file
3@brief Convert R into Python
4"""
5from antlr4 import ParseTreeWalker
6from pyquickhelper.pycode import remove_extra_spaces_and_pep8
7from .RParser import RParser
8from .RLexer import RLexer
9from .antlr_grammar_use import parse_code
10from .rconverterListener import TreeStringListener
13def r2python(code: str, pep8=False, fLOG=None) -> str:
14 """
15 Converts a R script into Python.
17 @param code R string
18 @param pep8 modify the output to be compliant with pep8
19 @param fLOG logging function
20 @return Python string
22 .. _code-r2python:
24 The function uses a customized R grammar implemented with Antlr4.
25 Formula becomes strings. They should be handled with
26 `patsy <http://patsy.readthedocs.io/en/latest/>`_.
28 .. exref::
29 :title: Convert R into Python
31 .. runpython::
32 :showcode:
34 rscript = '''
35 nb=function(y=1930){
36 debut=1816
37 MatDFemale=matrix(D$Female,nrow=111)
38 colnames(MatDFemale)=(debut+0):198
39 cly=(y-debut+1):111
40 deces=diag(MatDFemale[:,cly[cly%in%1:199]])
41 return(c(B$Female[B$Year==y],deces))}
42 '''
44 from pyensae.languages import r2python
45 print(r2python(rscript, pep8=True))
47 Some patterns are not well migrated such expression ``a:b`` into ``range(a,b)``.
48 The grammar could be improved to detect the beginning of the expression but
49 for now, if the function fails to do the conversion, ``a:b`` must be written
50 into ``(a):b``. The same trick is sometimes needed for other patterns
51 such as the operator ``%in%`` which is converted into an intersection
52 of two sets.
54 Kwonws bugs:
56 * ``} else {`` needs to be replaced by ``} EOL else {``
57 * comment added at the end of line must be followed by an empty line
58 * ``m[,1]`` must be replaced by ``M[:,1]``
59 * formula ``~.`` is not translated
60 * ``%<%`` cannot be followed by an empty line
61 """
62 if fLOG:
63 fLOG( # pragma: no cover
64 "[r2python] parse ", len(code), "bytes")
65 parser = parse_code(code, RParser, RLexer)
66 if fLOG:
67 fLOG( # pragma: no cover
68 "[r2python] parse continue")
69 parsed = parser.parse()
70 if fLOG:
71 fLOG( # pragma: no cover
72 "[r2python] listen")
73 listen = TreeStringListener(parsed, fLOG=fLOG)
74 walker = ParseTreeWalker()
75 if fLOG:
76 fLOG( # pragma: no cover
77 "[r2python] walk")
78 walker.walk(listen, parsed)
79 if fLOG:
80 fLOG( # pragma: no cover
81 "[r2python] get code")
82 code = listen.get_python()
83 if pep8:
84 if fLOG:
85 fLOG( # pragma: no cover
86 "[r2python] pep8")
87 code = remove_extra_spaces_and_pep8(code, aggressive=True)
88 return code