Подтвердить что ты не робот

Что такое связь в R?

Я прочитал и успешно использовал ?connections в R, но я действительно не понимаю, что это такое.

Я получаю, что могу загрузить файл, прочитать и записать сжатый файл... (я понимаю, что результат использования коннекта (open, do stuff, close), но я действительно не понимаю, что они действительно делают, почему вы должны открывать и закрывать их и т.д.).

Я надеюсь, что это также поможет мне понять, как их более эффективно использовать (в основном, понимать механику происходящего, чтобы я мог эффективно отлаживать, когда что-то не работает).

4b9b3361

Ответ 1

Соединения были введены в R 1.2.0 и описаны Брайаном Рипли в первом выпуске R NEWS (теперь называемом журналом R) Январь 2001 (стр. 16-17) в качестве абстрактного интерфейса для потоков ввода-вывода, таких как файл, url, socket или pipe. В 2013 году Саймон Урбанек добавил Connections.h API C, который позволяет R-пакетам реализовать пользовательские типы соединений, такие как curl.

Одна из особенностей соединений заключается в том, что вы можете постепенно считывать или записывать фрагменты данных из/в соединение с помощью функций readBin, writeBin, readLines и writeLines. Это позволяет обрабатывать асинхронные данные, например, при работе с большими данными или сетевыми соединениями:

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

То же самое для записи, например. в файл:

tmp <- file(tempfile())
open(tmp, "w")
writeLines("A line", tmp)
writeLines("Another line", tmp)
close(tmp)

Откройте соединение как rb или wb для чтения/записи двоичных данных (называемых необработанными векторами в 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)

Соединение pipe() используется для запуска системной команды и текста канала в stdin или из stdout, как это было бы с оператором | в оболочке. Например. (давайте придерживаться примеров скручивания), вы можете запустить программу командной строки curl и передать вывод в 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)

Некоторые аспекты соединений немного запутывают: для постепенного чтения/записи данных необходимо явно указывать open() и close() соединение. Однако readLines и writeLines автоматически открывают и закрывают (но не уничтожают!) Неоткрытое соединение. В результате приведенный ниже пример будет читать первые 10 строк снова и снова, что не очень полезно:

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)

Еще одна проблема заключается в том, что API C может закрывать и уничтожать соединение, но R предоставляет только функцию close() , которая на самом деле означает destroy. После вызова close() в соединении он уничтожается и полностью бесполезен.

Для потоковой обработки данных формируется соединение, в котором вы хотите использовать шаблон следующим образом:

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

Пакет jsonlite в значительной степени зависит от соединений для импорта/экспорта ndjson:

library(jsonlite)
library(curl)
diamonds <- stream_in(curl("https://jeroen.github.io/data/diamonds.json"))

Потоковая передача (по умолчанию 1000 строк за раз) делает ее быстрой и эффективной для памяти:

library(nycflights13)
stream_out(flights, file(tmp <- tempfile()))
flights2 <- stream_in(file(tmp))
all.equal(flights2, as.data.frame(flights))

Наконец, одна приятная особенность соединений заключается в том, что сборщик мусора автоматически закроет их, если вы забудете это сделать, с раздражающим предупреждением:

con <- file(system.file("DESCRIPTION"), open = "r")
rm(con)
gc()

Ответ 2

Я пытаюсь получить какой-то CSV файл из ZIP файла, доступного в сети (LAN), и у меня возникает та же проблема "Ошибка в open.connection(con," rb ")": не удается открыть соединение В open.connection(con, "rb"): не удается открыть zip файл. /201812070000-XXXXX.zip:201812070000-XXXX/35_2018-12-06_23:19 '

я проверяю связь с isOpen (con) и получил ИСТИНА. Я не могу понять, почему он показывает эту ошибку. Может ли быть случай, когда R не может прочитать ":" в именах файлов?

заранее спасибо