¿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.


¿Podrías usar el paquete rJava en su lugar?
Joshua Ulrich

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
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 ...


8
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

5
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

1

Suponga que tiene un archivo llamado tommy.csv (sí, imaginativo, lo sé ...) que tiene el contenido de

col1 col2 \ n 1 1 \ n 2 2 \ n 3 3

donde cada línea está separada con un carácter de escape "\ n".

Este archivo se puede leer con la ayuda del allowEscapesargumento en formato read.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.


1

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

0

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.

foo bar baz
1 2 a
3 4 b

Ahora envuélvalo con text_to_tablecomillas y cualquier otro argumento para read.table.

text_to_table("foo bar baz
1 2 a
3 4 b", header = TRUE)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.