2017
Ирина Голощапова
Руководитель направления "Макроэкономический анализ", X5 Retail Group
Комбинация мощных и стабильных библиотек R и Python:
Комбинация имеющихся навыков программирования на R и Python:
различный уровень знаний каждого языка у сотрудников в рамках проекта
ваш опыт решения конкретных задач на разных языках
предпочтения по синтаксису
Command line tools. Исполнение скриптов с помощью командной строки + промежуточное хранение файлов на диске (filling air gap)
Interfacing R and Python. Одновременный запуск процессов R и Python и передача данных между ними в оперативной памяти (in-memory)
Другие подходы
Исполнение скриптов с помощью командной строки
<cmd_to_run> <path_to_script> <any_additional_args>  
| Command | Python | R | 
|---|---|---|
| Cmd | python path/to/myscript.py arg1 arg2 arg3 | Rscript path/to/myscript.R arg1 arg2 arg3 | 
| Fetch arguments | #list, 1st el. - file executedimport sysmy_args = sys.argv | #character vector of argsmyArgs <- commandArgs(trailingOnly = TRUE) | 
Промежуточное хранение файлов
| Medium Storage | Python | R | 
|---|---|---|
| Flat files | ======= | ======= | 
| csv | csv, pandas | readr, data.table | 
| json | json | jsonlite | 
| yaml | PyYAML | yaml | 
| Databases | ======= | ======= | 
| SQL | sqlalchemy, pandasql pyodbc | sqlite, RODBS, RMySQL, sqldf, dplyr | 
| NoSQL | PyMongo | RMongo | 
| Feather | ======= | ======= | 
| for data frames | feather | feather | 
| Numpy | ======= | ======= | 
| for numpy objects | numpy | RcppCNPy | 

# max.R
randomvals <- rnorm(75, 5, 0.5)
par(mfrow = c(1, 2))
hist(randomvals, xlab = 'Some random numbers')
plot(randomvals, xlab = 'Some random numbers', ylab = 'value', pch = 3)
# splitstr.py
import sys
# Get the arguments passed in
string = sys.argv[1]
pattern = sys.argv[2]
# Perform the splitting
ans = string.split(pattern)
# Join the resulting list of elements into a single newline
# delimited string and print
print('\n'.join(ans))
# calling R from Python
import subprocess
# Define command and arguments
command = 'Rscript'
path2script = 'path/to your script/max.R'
# Variable number of args in a list
args = ['11', '3', '9', '42']
# Build subprocess command
cmd = [command, path2script] + args
# check_output will run the command and store to result
x = subprocess.check_output(cmd, universal_newlines=True)
print('The maximum of the numbers is:', x)
# calling Python from R
command = "python"
# Note the single + double quotes in the string (needed if paths have spaces)
path2script ='"path/to your script/splitstr.py"'
# Build up args in a vector
string = "3523462---12413415---4577678---7967956---5456439"
pattern = "---"
args = c(string, pattern)
# Add path to script as first arg
allArgs = c(path2script, args)
output = system2(command, args=allArgs, stdout=TRUE)
print(paste("The Substrings are:\n", output))
| Библиотеки | Комментарии | 
|---|---|
| rpy2 | - C-level interface - прямая поддержка pandas - поддержка графики (+ggplot2) - слабая поддержка Windows | 
| pyper | - Python code - use of pipes (в среднем быстрее) - косвенная поддержка pandas - ограниченная поддержка графики - плохая документация | 
| pyrserve | - Python code - удаленные вычисления/Rserve - нет поддержки для таблиц | 
| Библиотеки | Комментарии | 
|---|---|
| reticulate | - хорошая документация - активное развитие (с авг 2016 г.) - волшебная функция py_run_file("script.py") | 
| rPython | - передача данных через json - непрямая передача таблиц - хорошая документация - слабая поддержка Windows - часто падает с Anaconda | 
| RSPython | - двухсторонний интерфейс - нет поддержки после 2005 - слабая поддержка Windows | 
from rpy2.robjects import pandas2ri # loading rpy2
from rpy2.robjects import r
pandas2ri.activate() # activating pandas module
df_iris_py = pandas2ri.ri2py(r['iris']) # from r data frame to pandas
df_iris_r = pandas2ri.py2ri(df_iris_py) # from pandas to r data frame 
plotFunc = r("""
   library(ggplot2)
   function(df){
   p <- ggplot(iris, aes(x = Sepal.Length, y = Petal.Length)) 
          + geom_point(aes(color = Species))
   print(p)
   ggsave('iris_plot.pdf', plot = p, width = 6.5, height = 5.5)
 }
""") # ggplot2 example
gr = importr('grDevices') # necessary to shut the graph off
plotFunc(df_iris_r)
gr.dev_off()
library(reticulate)
# aliasing the main module
py <- import_main()
# set parameters for Python directly from R session
py$pattern <- "---"
py$string = "3523462---12413415---4577678---7967956---5456439"
# run splitstr.py from the slide 11
result <- py_run_file('splitstr.py')
# read Python script result in R
result$ans
# [1] "3523462"  "12413415" "4577678"  "7967956"  "5456439"
library(rPython)
# data frames transportation
python.assign('iris_py_dict', iris) # r data.frame to python dict
python.exec('import pandas as pd')
# convert dict to pd data frame
python.exec('iris_py_df = pd.DataFrame(iris_py_dict)')
# convert pd df back to dict
python.exec('iris_py_dict = iris_py_df.to_dict(outtype = "list")') 
# dict to r list to data frame
iris_df <- data.frame(python.get('iris_py_dict')) 
# python get/python_load
python.load("hello_world.py") ## hello_world = 'hello' + 'world' +'!'
greeting <- python.get("hello_world")
print(greeting) # class character
Контакты для связи
    gmaili.o.goloshchapova@gmail.com
    githubirinagoloshchapova
    repohttp://bit.ly/D2D_2017_R_Py