Очистить код и сохранить нулевые значения от сбоев read.csv.sql - PullRequest
0 голосов
/ 19 октября 2018

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

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

write.csv(iris, "iris.csv", row.names = F)
library(sqldf)
csvFile <- "iris.csv"

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

# Step 1 (Assume these values are coming from UI)
spec <- 'setosa'
petwd <- 0.2

# Add quotes and make comma-separated:
spec <- toString(sprintf("'%s'", spec)) 
petwd <- toString(sprintf("'%s'", petwd)) 

# Step 2 - Conditionally read in the data, store in 'd'
d <- fn$read.csv.sql(csvFile, sql='select * from file where 
                                  "Species" in ($spec)'
                                  and "Petal.Width" in ($petwd)',
                     filter = list('gawk -f prog', prog = '{ gsub(/"/, ""); print }'))

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

Примечание: Я повторно использую код из этого аналогичного вопроса в этом вопросе.

ОБНОВЛЕНИЕ
Я хочу уточнитьчто я спрашиваюВот что я пытаюсь сделать:

Если поле, скажем, spec отображается как NA (то есть пользователь не выбрал ввод), то я хочу, чтобы оно фильтровалось как таковое (по умолчанию spec == EVERY SPEC):

# Step 2 - Conditionally read in the data, store in 'd'
d <- fn$read.csv.sql(csvFile, sql='select * from file where 
                                  "Petal.Width" in ($petwd)',
                     filter = list('gawk -f prog', prog = '{ gsub(/"/, ""); print }'))

Поскольку spec равно NA, если вы попытаетесь отфильтровать / прочитать файл, соответствующий spec == NA, он будет считывать пустой набор данных, так как нет значений NAв моих данных, следовательно, нарушая код и программу.Надеюсь, это прояснит это больше.

1 Ответ

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

Есть несколько проблем:

  • некоторые из упрощений, приведенных в ссылке в вопросе, не были соблюдены.
  • spec - скаляр, поэтому можно просто использовать '$spec'
  • petwd - это числовой скаляр, и SQL не требует кавычек вокруг чисел, поэтому просто используйте $petwd
  • , в вопросе говорится, что вы хотите обрабатывать пустые поля, но не так, как у насиспользовал csvfix, чтобы сопоставить их с -1, а также убрать кавычки.(Поочередно позвольте им войти и сделать это в R. Пустые числа будут отображаться как 0, а пустые поля символов будут проходить как поля символов нулевой длины.)
  • вы можете использовать [...] вместо "... "в SQL

Приведенный ниже код работал для меня как в Windows, так и в Ubuntu Linux с оболочкой bash.

library(sqldf)

spec <- 'setosa'
petwd <- 0.2

d <- fn$read.csv.sql(
  "iris.csv", 
  sql = "select * from file where [Species] = '$spec' and [Petal.Width] = $petwd", 
  verbose = TRUE, 
  filter = 'csvfix map -smq -fv "" -tv -1'
)

Обновление

ОтносительноВ конце вопроса было уточнено, что NA может быть в spec, а не в данных, которые считываются, и что если spec - это NA, то условие, включающее spec, должно рассматриваться как ИСТИНА.В этом случае просто разверните условие SQL where, чтобы обработать его следующим образом.

spec <- NA
petwd <- 0.2

d <- fn$read.csv.sql(
  "iris.csv", 
  sql = "select * from file 
         where ('$spec' == 'NA' or [Species] = '$spec') and [Petal.Width] = $petwd", 
  verbose = TRUE, 
  filter = 'csvfix echo -smq'
)

Вышеприведенное вернет все строки, для которых Petal.Width равно 0,2.

...