fread: пустая строка («») в na.strings не интерпретируется как NA

#r #data.table #na #fread #read.table

#r #data.table #na #fread #read.table

Вопрос:

Как я могу fread() установить "" значение a NA для всех переменных, включая символьные переменные?

Я импортирую файл .csv, в котором отсутствующие значения являются пустыми строками ( "" ; без пробела). Я хочу "" , чтобы меня интерпретировали как пропущенное значение NA и попробовали `na.strings = «» без успеха:

 data <- fread("file.csv", na.strings = "")

unique(data$character_variable)
# [1] "abc" "def"      ""            
  

С другой стороны, когда я использую read.csv with na.strings = "" , "" они превращаются в NA s даже для символьных переменных. Это результат, который я хочу.

 data <- read.csv("file.csv", na.strings = "")

unique(data$character_variable)
# [1] "abc" "def"      NA
  

Версии

  • R версия 3.6.1 (2019-07-05)
  • data.table_1.12.8

Комментарии:

1. Я могу воспроизвести проблему со следующей строкой "anxn""" @GregorThomas

Ответ №1:

Ну, вы не можете, если ваш csv-файл выглядит так

 a,b
x,y
"",1
  

Обратите внимание, что все, что находится внутри "" , обрабатывается как строковый литерал, потому "" что это escape-символы. В этом смысле ,"", в файле csv просто означает пустую строку, но не пропущенное значение (т.е. ,, ). Я бы счел это хорошей функцией для обеспечения согласованности. Это также написано в разделе na.strings документации fread :

Символьный вектор строк, которые должны интерпретироваться как NA значения. По умолчанию ",," для столбцов всех типов, включая type character , считывается как NA для согласованности. ,"", является однозначным и читается как пустая строка. Чтобы читать ,NA, как NA , установите na.strings="NA" . Чтобы читать ,, как пустую строку "" , установите na.strings=NULL . Когда они встречаются в файле, строки в na.strings не должны отображаться в кавычках, поскольку именно так строковый литерал ,"NA", отличается ,NA, , например , от when na.strings="NA" .

С другой стороны, вы можете заметить, что если файл выглядит следующим образом

 a,b
1,y
"",1
  

, тогда пустая строка будет преобразована в NA . Однако я думаю, что это не ошибка, потому что такое поведение, вероятно, является следствием принудительного ввода типа синтаксическим анализатором. В Details разделе того же документа вы можете видеть, что

Наименьший тип для каждого столбца выбирается из упорядоченного списка: logical , integer , integer64 , double , character .

Поэтому столбец a сначала считывается как символьный столбец, а затем преобразуется в целочисленный. Пустая строка по-прежнему считывается как есть, но принудительно преобразуется в an NA_integer_ на втором шаге.

Комментарии:

1. Итак, по сути, fread() обрабатывает «» иначе, чем read.csv()?

2. Да, я бы так сказал.

3. Кроме того, в моем примере переменная была истинной символьной переменной, в отличие от c(«»,1), которая в данном случае мне нужна числовая: c(NA, 1) . Имеет ли значение, что переменная действительно символьная?

4. ДА. Как указано в документации fread , символьный тип является максимально возможным типом, поэтому принудительное ввод типа не выполняется. Вы просто получите пустую строку в результирующем фрейме данных. С другой стороны, если существует возможный более низкий тип, столбец будет дополнительно приведен к этому типу. Вот почему вы можете видеть c(NA,1), даже если столбец на самом деле является чем-то вроде c («»,1) . fread выполняет для вас принудительное ввод типа, например as.numeric(c("",1)) , молча.

5. Я рад видеть, что люди так хорошо читают руководства. Да, это того стоит!