Gibt es eine Möglichkeit, read.csv zum Lesen von einem Zeichenfolgenwert anstelle einer Datei in R zu verwenden?

82

Ich schreibe ein R-Paket, in dem der R-Code mit einer Java-Anwendung kommuniziert. Die Java-Anwendung gibt eine CSV-formatierte Zeichenfolge aus, und ich möchte, dass der R-Code die Zeichenfolge direkt lesen und in einen data.frame konvertieren kann.

Tommy Chheng
quelle
Könnten Sie stattdessen das rJava-Paket verwenden?
Joshua Ulrich
Vielleicht könnten Sie mit allowEscapes (in read.table) herumspielen. Stellen Sie einfach sicher, dass die Java-Ausgabe \ n verwendet, um Zeilen zu unterbrechen.
Roman Luštrik
@Joshua Ich benutze rJava, um mit meinem Java-Programm zu sprechen. Ich denke, es ist effizienter, meine schweren Java-Objekte zuerst in Strings umzuwandeln, bevor sie an R. übergeben werden
Tommy Chheng
Tommy, warum denkst du, dass manuelle Serialisierung effizienter ist als das, was Simon in rJava eingegeben hat? Haben Sie irgendetwas davon bewertet?
Dirk Eddelbuettel
1
Vielleicht ist effizient das falsche Wort. Meine Eingabe ist ein Array von Hashmap-ähnlichen Objekten und meine Ausgabe ist ein R-Datenrahmen. In rJava wurde nichts angezeigt, mit dem ich ein Java-Objekt als data.frame darstellen könnte. Daher formatiere ich meine Objekte in eine Zeichenfolge und konvertiere sie dann in einen R data.frame. Effizientere Vorschläge zur Bewältigung dieses Problems wären willkommen.
Tommy Chheng

Antworten:

115

Bearbeiten einer 7 Jahre alten Antwort: Inzwischen ist dies dank des Arguments, das hinzugefügt wurde, viel einfacher :text=read.csv()

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> 

Ja, schauen Sie sich die Hilfe an für textConnection()- die sehr mächtige Vorstellung in R ist, dass im Wesentlichen alle Leser (wie z. B. read.table()und ihre Varianten) auf dieses Verbindungsobjekt zugreifen, bei dem es sich möglicherweise um eine Datei, eine Remote-URL oder eine Pipe handelt, die von einer anderen App eingeht , oder ... ein Text wie in Ihrem Fall.

Der gleiche Trick wird für sogenannte hier Dokumente verwendet:

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

Beachten Sie, dass dies eine einfache Möglichkeit ist, etwas zu erstellen , aber auch teuer ist, da alle Daten wiederholt analysiert werden. Es gibt andere Möglichkeiten, von Java nach R zu gelangen, aber dies sollte Sie schnell zum Laufen bringen. Effizienz kommt als nächstes ...

Dirk Eddelbuettel
quelle
8
Neuere R-Versionen haben einen einfacheren Mechanismus, siehe die Antwort von @Adam Bradley in diesem Thread: stackoverflow.com/a/16349171/17523
Boris Gorelik
79

Beachten Sie, dass Sie in den aktuellen Versionen von R das nicht mehr benötigen. textConnection()Dies ist einfach möglich:

> 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
Adam Bradley
quelle
5
Ich weiß, dass dies selbst etwas spät ist, aber - es könnte vielleicht nützlich sein, dies als Bearbeitung der akzeptierten Antwort einzureichen, da es unwahrscheinlich ist, dass das OP jetzt die akzeptierte Antwort ändert, aber dies scheint nun die bessere Antwort zu sein?
Verschleierung
1
IMHO, das OP sollte die akzeptierte Antwort nicht akzeptieren und diese akzeptieren ...
Mischa
4

Ja. Zum Beispiel:

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
Joshua Ulrich
quelle
1

Angenommen, Sie haben eine Datei namens tommy.csv (ja, einfallsreich, ich weiß ...), die den Inhalt von enthält

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

Dabei wird jede Zeile durch ein Escapezeichen "\ n" getrennt.

Diese Datei kann mit Hilfe von allowEscapesArgumenten in gelesen werden read.table.

> read.table("tommy.csv", header = TRUE, allowEscapes = TRUE)

  col1 col2
1 col1 col2
2    1    1
3    2    2
4    3    3

Es ist nicht perfekt (Spaltennamen ändern ...), aber es ist ein Anfang.

Roman Luštrik
quelle
1

Mit einem Tidyverse-Ansatz können Sie einfach einen Textwert angeben

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
Kiryl Varanovich
quelle
0

Diese Funktion verpackt Dirks Antwort in eine bequeme Form. Es ist hervorragend für die Beantwortung von Fragen zu SO geeignet, bei denen der Fragesteller die Daten gerade auf dem Bildschirm gespeichert hat.

text_to_table <- function(text, ...)
{
   dfr <- read.table(tc <- textConnection(text), ...)
   close(tc)
   dfr
}

Um es zu verwenden, kopieren Sie zuerst die Bildschirmdaten und fügen Sie sie in Ihren Texteditor ein.

foo bar baz
1 2 a
3 4 b

Schließen Sie es nun mit text_to_tableAnführungszeichen und anderen Argumenten für ein read.table.

text_to_table("foo bar baz
1 2 a
3 4 b", header = TRUE)
Richie Cotton
quelle