Проблемы с обозначением read.csv.sql в r - PullRequest
0 голосов
/ 16 октября 2018

Я использую read.csv.sql для условного чтения данных ( мой набор данных очень большой, поэтому это решение я выбрал, чтобы отфильтровать его и уменьшить в размере до для чтения данных в ).Я столкнулся с проблемами памяти, прочитав полные данные, а затем отфильтровав их, поэтому важно использовать условное чтение, чтобы подмножество считывалось, а не полный набор данных.
Вот небольшойнабор данных, поэтому моя проблема может быть воспроизведена:

write.csv(iris, "iris.csv", row.names = F)

Я считаю, что нотация, которую вы должны использовать, очень неудобна при использовании read.csv.sql. Вот первый способ, которым я попытался прочитать файл, и он работаетно это грязно:

library(sqldf)
csvFile <- "iris.csv"

spec <- 'setosa'
sql <- paste0("select * from file where Species = '\"", spec,"\"'")
d1 <- read.csv.sql(file = csvFile, sql = sql)

Затем я нашел другой способ написать ту же запись в несколько более чистом виде:

sql <- paste0("select * from file where Species = '", spec,"'")
d2 <- read.csv.sql(file = csvFile, sql = sql, 
                   filter = list('gawk -f prog', prog = '{ gsub(/"/, ""); print }'))

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

d3 <- read.csv.sql(file = csvFile, 
                   sql = "select * from file where Species in 
                         ('\"setosa\"', '\"versicolor\"') ")

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

spec2 <- c('setosa', 'versicolor')
sql2 <- paste0("select * from file where Species in '", spec2,"'")
d4 <- read.csv.sql(file = csvFile, sql = sql2, 
                   filter = list('gawk -f prog', prog = '{ gsub(/"/, ""); print }'))

Но это не работает (кажется, что он читает только первое значение из вектора и пытается сопоставить его как таблицу).Я уверен, что это еще одна проблема с обозначениями, и я хотел бы помочь разобраться с этим фрагментом кода.
Кроме того, если у вас есть какие-либо советы / рекомендации по использованию read.csv.sql и работе с проблемами обозначений, я бы хотелуслышь их!

1 Ответ

0 голосов
/ 16 октября 2018

Проблема в том, что sqldf предоставляет средства предварительной обработки текста, но код, показанный в вопросе, не использует их, что делает его слишком сложным.

1) Что касается подстановки текста, используйте fn$(из gsubfn, который автоматически загружает sqldf), как обсуждалось на странице github для sqldf .Предполагая, что мы использовали quote = FALSE в файле write.csv, поскольку sqlite не обрабатывает кавычки изначально:

spec <- 'setosa'
out <- fn$read.csv.sql("iris.csv", "select * from file where Species = '$spec' ")

spec <- c("setosa", "versicolor")
string <- toString(sprintf("'%s'", spec)) # add quotes and make comma-separated
out <- fn$read.csv.sql("iris.csv", "select * from file where Species in ($string) ")

2) Что касается удаления двойных кавычек, более простым способом было бы использоватьследующий filter= аргумент:

read.csv.sql("iris.csv", filter = "tr -d \\042") # Windows

или

read.csv.sql("iris.csv", filter = "tr -d \\\\042") # Linux / bash

в зависимости от вашей оболочки.Первый работал для меня в Windows (с установленным Rtools и в PATH), а второй работал для меня в Linux с bash.Возможно, что для других оболочек могут потребоваться другие варианты.

2a) Другая возможность удаления кавычек - установить бесплатную утилиту csvfix (доступна в Windows , Linux и Mac ) в вашей системе, а затем используйте следующий аргумент filter=, который должен работать во всех оболочках, поскольку он не включает никаких символов, которые обычно интерпретируются R или Rбольшинство снарядов.Таким образом, следующее должно работать на всех платформах.

read.csv.sql("iris.csv", filter = "csvfix echo -smq")

2b) Еще одна кроссплатформенная утилита, которую можно использовать: xsv .Аргумент eol= необходим только в Windows, поскольку xsv создает окончания строк в стиле UNIX, но не повредит на других платформах, поэтому следующая строка должна работать на всех платформах.

read.csv.sql("iris.csv", eol = "\n", filter = "xsv fmt")

2c) sqldf также включает в себя программу awk (csv.awk), которую можно использовать.Он выводит символы новой строки в стиле UNIX, поэтому укажите в Windows eol = "\ n".На других платформах это не повредит, если вы укажете это, но вы можете опустить его, если хотите, так как это значение по умолчанию на этих платформах.

csv.awk <- system.file("csv.awk", package = "sqldf")
rm_quotes_cmd <- sprintf('gawk -f "%s"', csv.awk)
read.csv.sql("iris.csv", eol = "\n", filter = rm_quotes_cmd)

3) Что касается общих советов,обратите внимание, что аргумент verbose=TRUE для read.csv.sql может быть полезен для просмотра происходящего.

read.csv.sql("iris.csv", verbose = TRUE)
...