Как отключить научную нотацию в fwrite data.table в R?

Я хотел бы отключить научную запись при записи чисел в CSV файлы в data.table. Я могу сделать это с write.csv, используя options(scipen = 999), но не с fwrite. Пример:

require(data.table)
dt <- data.table("ID" = c("A", "B", "C", "D"), VALUE = c(0.0000001, 0.1234567, 1000000, 1234567))
options(scipen = 999)
write.csv(dt, row.names = FALSE)
# "ID","VALUE"
# "A",0.0000001
# "B",0.1234567
# "C",1000000
# "D",1234567
fwrite(dt, row.names = FALSE)
# ID,VALUE
# A,1e-07
# B,0.1234567
# C,1e+06
# D,1234567

Я бы хотел, чтобы строки A и C в fwrite записывались так же, как в write.csv. Я использую data.table версии 1.10.0. Ты знаешь как это сделать?

Ответ 1

Это теперь исправлено в data.table v1.12.4. Функция fwrite получает опцию scipen. Цитата с сайта data.table github: https://github.com/Rdatatable/data.table/blob/master/NEWS.md

"Получает scipen # 2020, номер 1 наиболее востребованной функции # 3189. По умолчанию используется getOption("scipen"), так что fwrite теперь будет учитывать опцию R так же, как base::write.csv и base::format, как и ожидалось. Параметр и имя опции оставлено таким же, как и у базового scipen R для согласованности и для облегчения поиска в Интернете. Это означает "научный штраф", т.е. количество символов, добавляемых к ширине, в пределах которой используется ненаучный числовой формат, если он будет соответствовать. Высокий штраф по существу отключает научный формат. Мы считаем, что обычной практикой является использование значения 999, однако, если вы используете 999, потому что ваши данные могут содержать очень длинные числа, такие как 10 ^ 300, fwrite необходимо учитывайте наихудшую ширину поля в распределении буфера для потока. Это может повлиять на пространство или время. Если вы испытываете замедления или недопустимое использование памяти, передайте verbose = TRUE, чтобы написать, проверить вывод и сообщить о проблеме. пока мы не сможем определить лучшую стратегию, может быть передать меньшее значение scipen, например, 50. Мы заметили, что fwrite(DT, scipen=50), по-видимому, пишет 10 ^ 50 точно, в отличие от базы R. Однако это может быть счастливой случайностью и не применимо вообще. Дальнейшая работа может потребоваться в этой области ".

Ответ 2

Вы можете попробовать это:

require(data.table)
#Sample data
dt <- data.table("ID" = c("A", "B", "C", "D"), VALUE = c(0.0000001, 0.1234567, 1000000, 1234567))
dt

   ID        VALUE
1:  A 1.000000e-07
2:  B 1.234567e-01
3:  C 1.000000e+06
4:  D 1.234567e+06

Идея решения:

dt$VALUE <- format(dt$VALUE, scientific = FALSE) 
fwrite(dt, row.names = FALSE)

Результаты

ID,VALUE
A,      0.0000001
B,      0.1234567
C,1000000.0000000
D,1234567.0000000

Изменить - удалить завершающие нули.

Кроме того, если вы хотите удалить конечные нули, вы можете добавить аргумент drop0trailing = TRUE в format.

dt$VALUE <- format(dt$VALUE, drop0trailing = TRUE, scientific = FALSE) 
fwrite(dt, row.names = FALSE)

ID,VALUE
A,      0.0000001
B,      0.1234567
C,1000000
D,1234567