Le connessioni sono state introdotte in R 1.2.0 e descritte da Brian Ripley nel primo numero di R NEWS (ora denominato The R Journal) di January 2001 (pagina 16-17) come interfaccia astratta di flussi IO come un file , url, socket o pipe. Nel 2013, Simon Urbanek ha aggiunto un'API C Connections.h che consente ai pacchetti R di implementare tipi di connessione personalizzati, come il pacchetto curl.
Una caratteristica di connessioni è che si può leggere o scrivere in modo incrementale pezzi di dati da/per la connessione utilizzando le funzioni readBin
, writeBin
, readLines
e writeLines
. Ciò consente l'elaborazione di dati asincrono, ad esempio quando si tratta di dati di grandi dimensioni o collegamenti di rete:
# Read the first 30 lines, 10 lines at a time
con <- url("http://jeroen.github.io/data/diamonds.json")
open(con, "r")
data1 <- readLines(con, n = 10)
data2 <- readLines(con, n = 10)
data3 <- readLines(con, n = 10)
close(con)
stessa per la scrittura, ad esempio in un file:
tmp <- file(tempfile())
open(tmp, "w")
writeLines("A line", tmp)
writeLines("Another line", tmp)
close(tmp)
Aprire la connessione come rb
o wb
per leggere/scrivere dati binari (chiamati vettori prime in R):
# 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)
Il collegamento pipe()
viene utilizzato per eseguire un comando di sistema e pipe text to stdin
o da stdout
come si farebbe con l'operatore |
in una shell. Per esempio. (Lascia il bastone con gli esempi ricciolo), è possibile eseguire il programma di linea di curl
di comando e inviare l'output a R:
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)
Alcuni aspetti di connessioni sono un po 'di confusione: per leggere in modo incrementale i dati/scrittura è necessario in modo esplicito open()
e close()
la connessione. Tuttavia, readLines
e writeLines
aprono e chiudono automaticamente (ma non distruggono!) Una connessione non aperta. Come risultato, l'esempio seguente leggerà le prime 10 righe più e più volte, che non è molto utile:
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)
Un altro punto è che l'API C può sia vicino e distruggere una connessione, ma R espone solo una funzione denominata close()
che in realtà significa distruggere. Dopo aver chiamato close()
su una connessione è distrutto e completamente inutile.
per lo streaming-elaborare i dati formano una connessione che si desidera utilizzare un modello come questo:
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)
}
}
Il pacchetto jsonlite
si basa molto sui collegamenti per importare/esportare i dati ndjson:
library(jsonlite)
library(curl)
diamonds <- stream_in(curl("https://jeroen.github.io/data/diamonds.json"))
Il lo streaming (di default 1000 righe alla volta) lo rende veloce ed efficiente nella memoria:
library(nycflights13)
stream_out(flights, file(tmp <- tempfile()))
flights2 <- stream_in(file(tmp))
all.equal(flights2, as.data.frame(flights))
.515.053.691,36321 milioni
Infine una caratteristica piacevole sulle connessioni è che il garbage collector si chiuderà automaticamente loro se si dimentica di farlo, con un avviso fastidioso:
con <- file(system.file("DESCRIPTION"), open = "r")
rm(con)
gc()
risposta Epic. Anche marginalmente affronta la questione dal PO. –