Las conexiones fueron introducidas en R 1.2.0 y descritas por Brian Ripley en el primer número de R NEWS (ahora llamado The R Journal) de Enero de 2001 (página 16-17) como una interfaz abstracta para flujos de E / S, como un archivo, una URL, un conector o una tubería. En 2013, Simon Urbanek agregó un Conexiones.h API de C que permite que los paquetes de R implementen tipos de conexión personalizados, como el rizo paquete.
Una característica de las conexiones es que puede leer o escribir de forma incremental datos desde / hacia la conexión utilizando el readBin
, writeBin
, readLines
y writeLines
funciones. Esto permite el procesamiento de datos asincrónico, por ejemplo, cuando se trata de grandes conexiones de datos o de red:
# Read the first 30 lines, 10 lines at a time
con <- url("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)
close(con)
Lo mismo para escribir, por ejemplo, en un archivo:
tmp <- file(tempfile())
open(tmp, "w")
writeLines("A line", tmp)
writeLines("Another line", tmp)
close(tmp)
Abra la conexión como rb
o wb
para leer / escribir datos binarios (llamados vectores sin procesar en R):
# Read the first 3000 bytes, 1000 bytes at a time
con <- url("https://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)
los pipe()
La conexión se utiliza para ejecutar un comando del sistema y canalizar texto a stdin
o de stdout
como harías con el |
operador en un caparazón. Por ejemplo (sigamos con los ejemplos de curl), puede ejecutar el curl
programa de línea de comando y canaliza la salida 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)
Algunos aspectos de las conexiones son un poco confusos: para leer / escribir datos de forma incremental, necesita explícitamente open()
y close()
la conexión. Sin embargo, readLines
y writeLines
abrir y cerrar automáticamente (¡pero no destruir!) una conexión sin abrir. Como resultado, el siguiente ejemplo leerá las primeras 10 líneas una y otra vez, lo que no es muy útil:
con <- url("https://jeroen.github.io/data/diamonds.json")
data1 <- readLines(con, n = 10)
data2 <- readLines(con, n = 10)
data3 <- readLines(con, n = 10)
identical(data1, data2)
Otro problema es que la API de C puede cerrar y destruir una conexión, pero R solo expone una función llamada close()
que en realidad significa destruir. Después de llamar close()
en una conexión se destruye y es completamente inútil.
Para procesar datos desde una conexión, desea utilizar un patrón como este:
stream <- function(){
con <- url("https://jeroen.github.io/data/diamonds.json")
open(con, "r")
on.exit(close(con))
while(length(txt <- readLines(con, n = 10))){
some_callback(txt)
}
}
los jsonlite
el paquete depende en gran medida de las conexiones para importar / exportar ndjson datos:
library(jsonlite)
library(curl)
diamonds <- stream_in(curl("https://jeroen.github.io/data/diamonds.json"))
La transmisión (por defecto 1000 líneas a la vez) lo hace rápido y eficiente en memoria:
library(nycflights13)
stream_out(flights, file(tmp <- tempfile()))
flights2 <- stream_in(file(tmp))
all.equal(flights2, as.data.frame(flights))
Finalmente, una buena característica sobre las conexiones es que el recolector de basura las cerrará automáticamente si se olvida de hacerlo, con una advertencia molesta:
con <- file(system.file("DESCRIPTION"), open = "r")
rm(con)
gc()