R добавляет дополнительные числа при чтении файла

Я пытался прочитать файл с полем даты и числовым полем. У меня есть данные на листе excel, и они выглядят примерно так:

Date          X       
1/25/2008     0.0023456
12/23/2008    0.001987

Когда я читаю это в R с помощью функции readxl::read_xlsx, данные в R выглядят так:

Date          X
1/25/2008     0.0023456000000000
12/23/2009    0.0019870000000000

Я пробовал ограничивать цифры с помощью таких функций, как округление, формат (nsmall = 7) и т. д., но, похоже, ничего не работает. Что я делаю не так? Я также попытался сохранить данные в виде csv и txt и прочитать их с помощью read.csv и read.delim, но снова столкнулся с той же проблемой. Любая помощь могла бы быть полезна!


person RHelp    schedule 04.09.2018    source источник
comment
Вы ищете что-то вроде X <- c(0.0023456, 0.001987, 0.3); sprintf("%g", X) ?   -  person jogo    schedule 04.09.2018
comment
Что-то похожее. sprint преобразует столбец в char, но я хочу сохранить его как числовое значение   -  person RHelp    schedule 04.09.2018
comment
Для числовых значений R использует en.wikipedia.org/wiki/IEEE_754#Basic_formats Пожалуйста, покажите нам, как должен выглядеть желаемый результат.   -  person jogo    schedule 04.09.2018


Ответы (3)


Как отмечено в комментариях к OP и другому ответу, эта проблема связана с тем, как математика с плавающей запятой обрабатывается на процессоре, используемом для запуска R, и его взаимодействием с параметром digits.

Для иллюстрации мы создадим электронную таблицу Excel с данными из OP и продемонстрируем, что происходит, когда мы настраиваем параметр options(digits=).

введите здесь описание изображения

Далее мы напишем короткий R-скрипт, чтобы проиллюстрировать, что происходит, когда мы настраиваем параметр digits.

> # first, display the number of significant digits set in R
> getOption("digits")
[1] 7
> 
> # Next, read data file from Excel
> library(xlsx)
> 
> theData <- read.xlsx("./data/smallNumbers.xlsx",1,header=TRUE)
> 
> head(theData)
        Date         X
1 2008-01-25 0.0023456
2 2008-12-23 0.0019870
> 
> # change digits to larger number to replicate SO question
> options(digits=17)
> getOption("digits")
[1] 17
> head(theData)
        Date                     X
1 2008-01-25 0.0023456000000000002
2 2008-12-23 0.0019870000000000001
>

Однако поведение при печати значащих цифр зависит от процессора/операционной системы, так как установка options(digits=16) приводит к следующему на машине с процессором Intel i7-6500U с Microsoft Windows 10:

> # what happens when we set digits = 16?
> options(digits=16)
> getOption("digits")
[1] 16
> head(theData)
        Date         X
1 2008-01-25 0.0023456
2 2008-12-23 0.0019870
> 
person Len Greski    schedule 04.09.2018
comment
Это поучительно! Благодаря тонну! - person RHelp; 05.09.2018

library(formattable)

x <- formattable(x, digits = 7, format = "f")

или вы можете добавить это, чтобы получить форматирование по умолчанию от R:

options(defaultPackages = "")

затем перезапустите R.

person Rendy Eza Putra    schedule 04.09.2018
comment
options(defaultPackages = "") делает что-то еще, и, как правило, это очень плохая идея. Но это также работает только в том случае, если это сделано до того, как R загрузит пакеты по умолчанию, например. в .Rprofile. Вы не можете сделать это, когда R уже запущен. Выполнение команды, а затем перезапуск R не будет иметь никакого эффекта. - person Konrad Rudolph; 04.09.2018
comment
Спасибо! Это тоже сработало. Хотя линейный график этой переменной с использованием ggplot по-прежнему показывает исходное количество цифр. Постараюсь разобраться с этим. - person RHelp; 04.09.2018

Возможно, проблема не в вашем исходном файле, поскольку вы говорите, что это происходит и с .csv и .txt.

Попробуйте проверить текущее значение параметра отображения цифр, запустив options()$digits

Если результат, например. 14 скорее всего проблема.

В этом случае попробуйте запустить команду r options(digits=8), которая установит отображаемые цифры = 8 для сеанса.

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

Обратитесь к ?options для получения дополнительной информации о настройках отображения цифр и других параметрах сеанса.

Изменить, чтобы улучшить исходный ответ и уточнить для будущих читателей:

  1. Изменение options(digits=x) вверх или вниз не меняет значение, которое сохраняется или считывается во внутреннюю память для переменных с плавающей запятой. Параметр сеанса digits просто изменяет способ печати значений с плавающей запятой, т.е. отображения на экране для общих функций печати в соответствии с документацией '?options`:

цифры: управляет количеством значащих цифр для печати при печати числовых значений.

  1. То, что ОП показал как проблему, с которой он столкнулся (R отображает больше десятичных знаков после последней цифры в десятичном числе, чем ожидал увидеть ОП), не было вызвано тем, что исходный файл был прочитан из Excel, т.е. учитывая, что у ОП была такая же проблема с CSV и TXT процесс импорта не вызвал проблем.

Если вы видите больше десятичных знаков, чем хотите по умолчанию, в распечатываемом/отображаемом выводе (например, для фреймов данных и числовых переменных), попробуйте проверить options()$digits и понять, что этот параметр просто используется по умолчанию для количества цифр, используемых в обычных методах отображения и печати R. ОДНАКО, это не влияет на хранение данных или переменных с плавающей запятой.

Что касается чисел с плавающей запятой, другой ответ здесь показывает, как установка option(digits=n) выше значения по умолчанию может помочь продемонстрировать некоторые особенности точности/отображения, связанные с точностью с плавающей запятой. Это отдельная проблема по сравнению с тем, что ОП отобразил в его примере, но это стоит понять.

Для гораздо более подробного и конкретного обсуждения точности с плавающей запятой, чем было бы уместно перефразировать здесь, стоит прочитать этот окончательный вопрос + ответ SO: Почему эти числа не равны?
Этот другой вопрос+ответ+обсуждение касается вопросов, касающихся точности с плавающей запятой, и содержит длинный, хорошо представленный список ссылок которые вы найдете полезными, если вам понадобится дополнительная информация по этому вопросу.

person krads    schedule 04.09.2018
comment
Спасибо! Это сработало. Но это ограничение будет применяться ко всем наборам данных и переменным, используемым в активном сеансе, верно? - person RHelp; 04.09.2018
comment
Параметр для цифр влияет только на то, как он печатается на экране в сеансе, а не на то, сколько цифр хранится в памяти. То есть, из файла справки options: digits: управляет количеством значащих цифр для печати при печати числовых значений. Это только предложение. Допустимые значения: 1...22, по умолчанию 7. - person krads; 04.09.2018