Die Verbindungen wurden in R 1.2.0 eingeführt und von Brian Ripley in der ersten Ausgabe von R NEWS (jetzt The R Journal) von January 2001 (Seite 16-17) als abstrahierte Schnittstelle zu IO-Streams wie einer Datei beschrieben , URL, Socket oder Pipe. Im Jahr 2013 fügte Simon Urbanek eine Connections.h C-API hinzu, die es R-Paketen ermöglicht, benutzerdefinierte Verbindungstypen wie das curl-Paket zu implementieren.
Ein Merkmal der Verbindungen ist, dass Sie schrittweise Stücke von Daten vom/zum Anschluss lesen oder schreiben können mit den readBin
, writeBin
, readLines
und writeLines
Funktionen. Dies ermöglicht eine asynchrone Datenverarbeitung, beispielsweise wenn es um große Daten oder Netzwerkverbindungen geht:
Gleiches zum Schreiben, z.B. in einer Datei:
tmp <- file(tempfile())
open(tmp, "w")
writeLines("A line", tmp)
writeLines("Another line", tmp)
close(tmp)
Öffnen die Verbindung als rb
oder wb
in binäre Daten (so genannte rohe Vektoren in R) lesen/schreiben:
# Read the first 3000 bytes, 1000 bytes at a time
con <- url("http://jeroen.github.io/data/diamonds.json")
open(con, "rb")
data1 <- readBin(con, raw(), n = 1000)
data2 <- readBin(con, raw(), n = 1000)
data3 <- readBin(con, raw(), n = 1000)
close(con)
Die pipe()
Verbindung wird verwendet, um einen Systembefehl auszuführen und Pipe Text zu stdin
oder von stdout
wie Sie mit dem Operator |
in einer Shell tun würde. Z.B. (Lässt Stick mit den curl Beispiele), können Sie die curl
Kommandozeilenprogramm und Rohr der Ausgang R laufen:
con <- pipe("curl -H 'Accept: application/json' https://jeroen.github.io/data/diamonds.json")
open(con, "r")
data1 <- readLines(con, n = 10)
data2 <- readLines(con, n = 10)
data3 <- readLines(con, n = 10)
Einige Aspekte der Verbindungen sind etwas verwirrend: inkrementell lesen/schreiben Daten explizit zu müssen open()
und close()
die Verbindung. readLines
und writeLines
öffnen und schließen (aber nicht zerstören!) Automatisch eine ungeöffnete Verbindung. Als Ergebnis wird das folgende Beispiel die ersten 10 Zeilen über gelesen und immer wieder was nicht sehr nützlich ist:
con <- url("http://jeroen.github.io/data/diamonds.json")
data1 <- readLines(con, n = 10)
data2 <- readLines(con, n = 10)
data3 <- readLines(con, n = 10)
identical(data1, data2)
Eine andere gotcha ist, dass die C-API kann sowohl in der Nähe und zerstören eine Verbindung, aber R macht nur eine Funktion verfügbar, die close()
genannt wird, die eigentlich zerstören bedeutet. Nach dem Aufruf von close()
auf einer Verbindung ist es zerstört und völlig nutzlos.
Um Stream-Prozessdaten bilden eine Verbindung möchten Sie so ein Muster verwenden:
stream <- function(){
con <- url("http://jeroen.github.io/data/diamonds.json")
open(con, "r")
on.exit(close(con))
while(length(txt <- readLines(con, n = 10))){
some_callback(txt)
}
}
Das jsonlite
Paket stark auf Verbindungen angewiesen importieren/exportieren ndjson Daten:
library(jsonlite)
library(curl)
diamonds <- stream_in(curl("https://jeroen.github.io/data/diamonds.json"))
Die Streaming (standardmäßig 1000 Zeilen zu einer Zeit) macht es schnell und Speicher effizient:
library(nycflights13)
stream_out(flights, file(tmp <- tempfile()))
flights2 <- stream_in(file(tmp))
all.equal(flights2, as.data.frame(flights))
schließlich ein nettes Feature über Verbindungen ist, dass der Garbage Collector sie automatisch geschlossen werden, wenn Sie dies tun vergessen, mit einer lästigen Warnung:
con <- file(system.file("DESCRIPTION"), open = "r")
rm(con)
gc()
Epische Antwort. Sprechen Sie die Frage des OP sogar marginal an. –