¿Hay alguna forma de usar read.csv para leer desde un valor de cadena en lugar de un archivo en R?
82
Estoy escribiendo un paquete R donde el código R habla con una aplicación Java. La aplicación Java genera una cadena con formato CSV y quiero que el código R pueda leer directamente la cadena y convertirla en un data.frame.
Tal vez podrías jugar con allowEscapes (en read.table). Solo asegúrese de que la salida de Java use \ n para dividir líneas.
Roman Luštrik
@Joshua Estoy usando rJava para hablar con mi programa Java. Creo que es más eficiente convertir mis objetos java pesados en cadenas primero antes de pasarlos a R.
tommy chheng
Tommy, ¿qué te hace pensar que la serialización manual es más eficiente que lo que Simon puso en rJava? ¿Evaluó algo de esto?
Dirk Eddelbuettel
1
tal vez eficiente es la palabra incorrecta. Mi entrada es una matriz de objetos tipo hashmap y mi salida es un R data.frame. No vi nada en rJava que me permita representar un objeto java como data.frame, así que formateo mis objetos en una cadena y luego los convierto en un data.frame R. Se agradecería cualquier sugerencia más eficaz para solucionar este problema.
tommy chheng
Respuestas:
116
Editando una respuesta de 7 años: a estas alturas, esto es mucho más simple gracias al text=argumento que se ha agregado read.csv()y similar:
R> data <- read.csv(text="flim,flam
+ 1.2,2.2
+ 77.1,3.14")
R> data
flim flam
11.22.20277.13.14
R>
Sí, mire la ayuda para textConnection(): la noción muy poderosa en R es que esencialmente todos los lectores (como, por ejemplo, read.table()y sus variantes) acceden a estos objetos de conexión que pueden ser un archivo, una URL remota o una tubería proveniente de otra aplicación. , o ... algún texto como en tu caso.
El mismo truco se utiliza para los llamados documentos aquí:
> lines <- "
+ flim,flam
+ 1.2,2.2
+ 77.1,3.14
+ "
> con <- textConnection(lines)
> data <- read.csv(con)
> close(con)
> data
flim flam
11.22.20277.13.14
>
Tenga en cuenta que esta es una forma sencilla de crear algo, pero también es costosa debido al análisis repetido de todos los datos. Hay otras formas de pasar de Java a R, pero esto debería ayudarte a empezar rápidamente. La eficiencia viene a continuación ...
Las versiones de R más recientes tienen un mecanismo más simple, vea la respuesta de @Adam Bradley en este hilo: stackoverflow.com/a/16349171/17523
Boris Gorelik
79
Tenga en cuenta que en las versiones actuales de R, ya no necesita textConnection(), es posible simplemente hacer esto:
> states.str='"State","Abbreviation"
+ "Alabama","AL"
+ "Alaska","AK"
+ "Arizona","AZ"
+ "Arkansas","AR"
+ "California","CA"'
> read.csv(text=states.str)
State Abbreviation
1 Alabama AL
2 Alaska AK
3 Arizona AZ
4 Arkansas AR
5 California CA
Sé que esto en sí es un poco tarde, pero tal vez podría ser útil enviar esto como una edición de la respuesta aceptada, ya que es poco probable que el OP cambie ahora la respuesta aceptada, pero ¿esta ahora parece la mejor respuesta?
ofuscación
1
En mi humilde opinión, el OP debería rechazar la respuesta aceptada y aceptar esta ...
Mischa
4
Si. Por ejemplo:
string <- "this,will,be\na,data,frame"
x <- read.csv(con <- textConnection(string), header=FALSE)
close(con)
#> x# V1 V2 V3#1 this will be#2 a data frame
Esta función envuelve la respuesta de Dirk en una forma conveniente. Es brillante para responder preguntas sobre SO, donde el autor de la pregunta acaba de descargar los datos en pantalla.
Respuestas:
Editando una respuesta de 7 años: a estas alturas, esto es mucho más simple gracias al
text=
argumento que se ha agregadoread.csv()
y similar:R> data <- read.csv(text="flim,flam + 1.2,2.2 + 77.1,3.14") R> data flim flam 1 1.2 2.20 2 77.1 3.14 R>
Sí, mire la ayuda para
textConnection()
: la noción muy poderosa en R es que esencialmente todos los lectores (como, por ejemplo,read.table()
y sus variantes) acceden a estos objetos de conexión que pueden ser un archivo, una URL remota o una tubería proveniente de otra aplicación. , o ... algún texto como en tu caso.El mismo truco se utiliza para los llamados documentos aquí:
> lines <- " + flim,flam + 1.2,2.2 + 77.1,3.14 + " > con <- textConnection(lines) > data <- read.csv(con) > close(con) > data flim flam 1 1.2 2.20 2 77.1 3.14 >
Tenga en cuenta que esta es una forma sencilla de crear algo, pero también es costosa debido al análisis repetido de todos los datos. Hay otras formas de pasar de Java a R, pero esto debería ayudarte a empezar rápidamente. La eficiencia viene a continuación ...
fuente
Tenga en cuenta que en las versiones actuales de R, ya no necesita
textConnection()
, es posible simplemente hacer esto:> states.str='"State","Abbreviation" + "Alabama","AL" + "Alaska","AK" + "Arizona","AZ" + "Arkansas","AR" + "California","CA"' > read.csv(text=states.str) State Abbreviation 1 Alabama AL 2 Alaska AK 3 Arizona AZ 4 Arkansas AR 5 California CA
fuente
Si. Por ejemplo:
string <- "this,will,be\na,data,frame" x <- read.csv(con <- textConnection(string), header=FALSE) close(con) #> x # V1 V2 V3 #1 this will be #2 a data frame
fuente
Suponga que tiene un archivo llamado tommy.csv (sí, imaginativo, lo sé ...) que tiene el contenido de
donde cada línea está separada con un carácter de escape "\ n".
Este archivo se puede leer con la ayuda del
allowEscapes
argumento en formatoread.table
.> read.table("tommy.csv", header = TRUE, allowEscapes = TRUE) col1 col2 1 col1 col2 2 1 1 3 2 2 4 3 3
No es perfecto (modificar los nombres de las columnas ...), pero es un comienzo.
fuente
Usando un enfoque tidyverse, puede simplemente especificar un valor de texto
library(readr) read_csv(file = "col1, col2\nfoo, 1\nbar, 2") # A tibble: 2 x 2 col1 col2 <chr> <dbl> 1 foo 1 2 bar 2
fuente
Esta función envuelve la respuesta de Dirk en una forma conveniente. Es brillante para responder preguntas sobre SO, donde el autor de la pregunta acaba de descargar los datos en pantalla.
text_to_table <- function(text, ...) { dfr <- read.table(tc <- textConnection(text), ...) close(tc) dfr }
Para usarlo, primero copie los datos en pantalla y péguelos en su editor de texto.
Ahora envuélvalo con
text_to_table
comillas y cualquier otro argumento pararead.table
.text_to_table("foo bar baz 1 2 a 3 4 b", header = TRUE)
fuente