studio - Ejecutando script R desde python
r vs python for machine learning (5)
Creo que vale la pena mirar RPy2, aquí hay una presentación genial en R-bloggers.com para comenzar:
http://www.r-bloggers.com/accessing-r-from-python-using-rpy2/
Esencialmente, le permite tener acceso a las bibliotecas R con objetos R que proporcionan una interfaz de alto y bajo nivel.
Aquí están los documentos de la versión más reciente: https://rpy2.readthedocs.io
Me gusta señalar a los usuarios de Python a Anaconda, y si usa el administrador de paquetes, conda
, para instalar rpy2
, también se asegurará de que instale R.
$ conda install rpy2
Y aquí hay un vignet basado en la introducción de los documentos:
>>> from rpy2 import robjects
>>> pi = robjects.r[''pi'']
>>> pi
R object with classes: (''numeric'',) mapped to:
<FloatVector - Python:0x7fde1c00a088 / R:0x562b8fbbe118>
[3.141593]
>>> from rpy2.robjects.packages import importr
>>> base = importr(''base'')
>>> utils = importr(''utils'')
>>> import rpy2.robjects.packages as rpackages
>>> utils = rpackages.importr(''utils'')
>>> packnames = (''ggplot2'', ''hexbin'')
>>> from rpy2.robjects.vectors import StrVector
>>> names_to_install = [x for x in packnames if not rpackages.isinstalled(x)]
>>> if len(names_to_install) > 0:
... utils.install_packages(StrVector(names_to_install))
Y ejecutando un fragmento de R:
>>> robjects.r(''''''
... # create a function `f`
... f <- function(r, verbose=FALSE) {
... if (verbose) {
... cat("I am calling f()./n")
... }
... 2 * pi * r
... }
... # call the function `f` with argument value 3
... f(3)
... '''''')
R object with classes: (''numeric'',) mapped to:
<FloatVector - Python:0x7fde1be0d8c8 / R:0x562b91196b18>
[18.849556]
Y una pequeña demo de gráficos autocontenidos:
from rpy2.robjects.packages import importr
graphics = importr(''graphics'')
grdevices = importr(''grDevices'')
base = importr(''base'')
stats = importr(''stats'')
import array
x = array.array(''i'', range(10))
y = stats.rnorm(10)
grdevices.X11()
graphics.par(mfrow = array.array(''i'', [2,2]))
graphics.plot(x, y, ylab = "foo/bar", col = "red")
kwargs = {''ylab'':"foo/bar", ''type'':"b", ''col'':"blue", ''log'':"x"}
graphics.plot(x, y, **kwargs)
m = base.matrix(stats.rnorm(100), ncol=5)
pca = stats.princomp(m)
graphics.plot(pca, main="Eigen values")
stats.biplot(pca, main="biplot")
Busqué esta pregunta y encontré algunas respuestas, pero ninguna de ellas parece funcionar. Este es el script que estoy usando en Python para ejecutar mi script R
import subprocess
retcode = subprocess.call("/usr/bin/Rscript --vanilla -e ''source(/"/pathto/MyrScript.r/")''", shell=True)
y me sale este error:
Error in read.table(file = file, header = header, sep = sep, quote = quote, :
no lines available in input
Calls: source ... withVisible -> eval -> eval -> read.csv -> read.table
Execution halted
y aquí está el contenido de mi script R (¡bastante simple!)
data = read.csv(''features.csv'')
data1 = read.csv("BagofWords.csv")
merged = merge(data,data1)
write.table(merged, "merged.csv",quote=FALSE,sep=",",row.names=FALSE)
for (i in 1:length(merged$fileName))
{
fileConn<-file(paste("output/",toString(merged$fileName[i]),".txt",sep=""))
writeLines((toString(merged$BagofWord[i])),fileConn)
close(fileConn)
}
El script r funciona bien cuando uso source(''MyrScript.r'')
en r línea de comandos. Además, cuando intento utilizar el comando exacto que paso a la función subprocess.call
(es decir, /usr/bin/Rscript --vanilla -e ''source("/pathto/MyrScript.r")''
) en mi línea de comando funciona encontrar, realmente no entiendo cuál es el problema.
Intente agregar una línea al principio de su script R que diga:
setwd("path-to-working-directory")
Excepto, reemplace la ruta con la ruta a la carpeta que contiene los archivos features.csv
y BagofWords.csv
.
Creo que el problema que tienes es que cuando ejecutas este script desde R, tu directorio de trabajo ya es la ruta correcta, pero cuando ejecutas el script desde Python, aparece de forma predeterminada en un directorio de trabajo en otro lugar (probablemente la parte superior del directorio de usuarios). ).
Al agregar la línea adicional al comienzo de su script R, está configurando explícitamente el directorio de trabajo y el código para leer en estos archivos funcionará. Alternativamente, puede reemplazar los nombres de archivo en read.csv()
con las rutas de archivo completas de estos archivos.
@dmontaner sugirió esta posibilidad en su respuesta:
El proceso puede fallar debido a cosas simples como que su directorio de trabajo no sea el que usted cree.
No confiaría demasiado en la fuente dentro de la llamada a Rscript
ya que es posible que no entiendas por completo dónde ejecutas tus diferentes sesiones R anidadas . El proceso puede fallar debido a cosas simples como que su directorio de trabajo no sea el que usted cree.
Rscript
permite ejecutar directamente un script (vea man Rscript
si está usando Linux).
Entonces puedes hacerlo directamente:
subprocess.call ("/usr/bin/Rscript --vanilla /pathto/MyrScript.r", shell=True)
o mejor analizando el comando Rscript
y sus parámetros como una lista
subprocess.call (["/usr/bin/Rscript", "--vanilla", "/pathto/MyrScript.r"])
Además, para hacer las cosas más fáciles, puedes crear un archivo ejecutable R. Para esto solo necesitas agregar esto en la primera línea del script:
#! /usr/bin/Rscript
Y le dan derechos de ejecución. Vea here para más detalles.
Luego puedes hacer tu llamada a Python como si fuera cualquier otro comando o script de shell:
subprocess.call ("/pathto/MyrScript.r")
No sugeriría utilizar una llamada al sistema para que haya muchas diferencias entre python y R, especialmente cuando se transmiten datos.
Hay muchas bibliotecas estándar para llamar a R desde Python para elegir ver esta answer
Si solo desea ejecutar un script, puede usar el system("shell command")
de la sys
disponible por el sistema de import sys
. Si tiene una salida útil, puede imprimir el resultado con " > outputfilename"
al final de su comando de shell.
Por ejemplo:
import sys
system("ls -al > output.txt")