Я пытаюсь импортировать CSV с пробелами, читаемыми как ""
. К сожалению, сейчас они все читают как "NA"
.
Чтобы лучше продемонстрировать проблему, я также показываю, как NA
, "NA"
и ""
все сопоставляются с одним и тем же (кроме самого нижнего примера), что предотвратит простой обходной путь dt[is.na(dt)] <- ""
> write.csv(matrix(c("0","",NA,"NA"),ncol = 2),"MRE.csv")
Открывая это в блокноте, это выглядит так
"","V1","V2"
"1","0",NA
"2","","NA"
Итак, читаю это обратно ...
> fread("MRE.csv")
V1 V1 V2
1: 1 0 NA
2: 2 NA NA
Документация, кажется, предлагает это, но это не работает, как описано
> fread("MRE.csv",na.strings = NULL)
V1 V1 V2
1: 1 0 NA
2: 2 NA NA
Также пробовал это, которое считывает NA
как фактическое NA, но проблема остается для пустой строки, которая читается как "NA"
> fread("MRE.csv",colClasses=c(V1="character",V2="character"))
V1 V1 V2
1: 1 0 <NA>
2: 2 NA NA
> fread("MRE.csv",colClasses=c(V1="character",V2="character"))[,V2]
[1] NA "NA"
Data.table версия 1.11.4
R версия 3.5.1
1 ответ
Здесь происходит несколько возможных вещей:
Независимо от того, что вы пишете здесь
"0"
, функция чтения (fread
) делает вывод на основе просмотра части файла. Это не редкость (readr
тоже делает), и это можно контролировать (сcolClasses=
).Это может быть уникальным для вашего вопроса здесь (а не для ваших реальных данных), но ваш вызов
write.csv
неявно помещает буквальные буквыNA
в файл (не путать с"NA"
где у вас есть буквальная строка). Это может сбивать с толку, даже если вы переопределите с помощьюcolClasses=
.Возможно, вы уже знаете это, но поскольку
fread
предполагает, что эти столбцы на самом деле являютсяinteger
классами, они не могут содержать пустые строки: после определения числового столбца все, что не является числовым, будетNA
.
Давайте переделаем вашу первую сторону генерации csv, чтобы убедиться, что мы не запутаем ситуацию.
write.csv(matrix(c("0","",NA,"NA"),ncol = 2), "MRE.csv", na="")
(Ниже я использую оператор канала magrittr
%>%
только для презентации, это не обязательно.)
Первый пример демонстрирует вывод fread
. Второй показывает, что мы переопределяем это поведение, и теперь у нас есть пустые строки в каждом месте NA
, которое не является буквальной строкой "NA"
.
fread("MRE.csv") %>% str
# Classes 'data.table' and 'data.frame': 2 obs. of 3 variables:
# $ V1: int 1 2
# $ V1: int 0 NA
# $ V2: logi NA NA
# - attr(*, ".internal.selfref")=<externalptr>
fread("MRE.csv", colClasses="character") %>% str
# Classes 'data.table' and 'data.frame': 2 obs. of 3 variables:
# $ V1: chr "1" "2"
# $ V1: chr "0" ""
# $ V2: chr "" "NA"
# - attr(*, ".internal.selfref")=<externalptr>
Это также можно контролировать для отдельных столбцов. Одна проблема с этим примером заключается в том, что fread
по какой-то причине заставляет столбец с именами строк называться V1
, так же, как и следующий столбец. Мне это кажется ошибкой, возможно, вы можете посмотреть Проблемы Rdatatable и, возможно, опубликуйте новую. (Я могу ошибаться, возможно, это преднамеренное / известное поведение.)
Из-за этого переопределение для каждого столбца, кажется, останавливается при первом появлении имени столбца.
fread("MRE.csv", colClasses=c(V1="character", V2="character")) %>% str
# Classes 'data.table' and 'data.frame': 2 obs. of 3 variables:
# $ V1: chr "1" "2"
# $ V1: int 0 NA
# $ V2: chr "" "NA"
# - attr(*, ".internal.selfref")=<externalptr>
Один из способов обойти это - использовать безымянный вектор, требующий того же количества классов, что и количество столбцов:
fread("MRE.csv", colClasses=c("character","character","character")) %>% str
# Classes 'data.table' and 'data.frame': 2 obs. of 3 variables:
# $ V1: chr "1" "2"
# $ V1: chr "0" ""
# $ V2: chr "" "NA"
# - attr(*, ".internal.selfref")=<externalptr>
Другой способ (спасибо @thelatemail) - список:
fread("MRE.csv", colClasses=list(character=2:3)) %>% str
# Classes 'data.table' and 'data.frame': 2 obs. of 3 variables:
# $ V1: int 1 2
# $ V1: chr "0" ""
# $ V2: chr "" "NA"
# - attr(*, ".internal.selfref")=<externalptr>
Боковое примечание: если вам нужно сохранить их как ints / nums, тогда:
если вас беспокоит то, как это влияет на последующие расчеты, вы можете:
- исправить источник данных, чтобы не указывать значения NULL;
- отфильтровать неполные наблюдения (строки); или
- исправить вычисления, чтобы разумно обрабатывать недостающие данные.
если вас беспокоит то, как это выглядит в отчете, то в любом инструменте, который вы используете для отображения в отчете, должен быть механизм для отображения значений
NA
; например, установкаoptions(knitr.kable.NA="")
передknitr::kable(...)
представит их как пустые строки.Если вас беспокоит то, как это выглядит на консоли , у вас есть два варианта:
- вмешиваться в данные, перебирая каждый (предполагаемый) столбец и изменяя значения
NA
на""
; это работает только со столбцамиcharacter
и необратимо; или - напишите свой собственный подкласс
data.frame
, который изменяет его отображение на консоли; Преимущество этого в том, что он не разрушает; проблема в том, что вам нужно переклассифицировать каждый объект, для которого вы хотите это поведение, и большинство (если не все) функций, которые выводят кадры, скорее всего, непреднамеренно удаляют этот класс из вашего ввода. (Для этого вам нужно написать S3-методprint
для вашего подкласса.)
- вмешиваться в данные, перебирая каждый (предполагаемый) столбец и изменяя значения
Похожие вопросы
Новые вопросы
r
R - это бесплатный язык программирования с открытым исходным кодом и программная среда для статистических вычислений, биоинформатики, визуализации и общих вычислений. Пожалуйста, предоставьте минимальные и воспроизводимые примеры вместе с желаемым результатом. Используйте dput () для данных и укажите все небазовые пакеты с вызовами library (). Не вставляйте изображения для данных или кода, вместо этого используйте блоки кода с отступом. По вопросам, связанным со статистикой, используйте https://stats.stackexchange.com.