Здесь возможно несколько вещей:
Независимо от того, что вы здесь пишете "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="")
(ниже я использую %>%
оператор трубы *1032* просто для презентации, это не требуется.)
Первый пример демонстрирует умозаключение 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>
Примечание: если вам нужно сохранить их в виде целых чисел / чисел, то:
, если вас интересует, как это повлияет на последующие вычисления, тогда вы можете:
- исправить источник данных таким образом, чтобы нули не предоставлялись;
- отфильтровать неполные наблюдения (строки);или
- исправьте расчеты, чтобы разумно обрабатывать отсутствующие данные.
, если вас беспокоит то, как он выглядит в отчете, то каким бы инструментом вы ни пользовалисьдля рендеринга в вашем отчете должен быть предусмотрен механизм отображения NA
значений;Например, установка options(knitr.kable.NA="")
перед knitr::kable(...)
представит их в виде пустых строк.
, если вас беспокоит то, как это выглядит на вашей консоли , у вас естьдва варианта:
- вмешиваться в данные путем итерации по каждому (предполагаемому) столбцу и изменения значений
NA
на ""
;это работает только на character
столбцах и является необратимым;или - написать свой собственный подкласс
data.frame
, который меняет способ его отображения на консоли;выгода для этого состоит в том, что это не разрушительно;проблема заключается в том, что вам необходимо переклассифицировать каждый объект, где вы хотите, чтобы это поведение, и большинство (если не все) функции, которые выводят кадры, вероятно, непреднамеренно удалят или пропустят этот класс из вашего ввода. (Для этого вам нужно написать метод S3 print
для вашего подкласса.)