Ответ 1
as
предназначен для принудительного ввода в новый class
, а double технически не является class
, а скорее a storage.mode
.
y <- x
storage.mode(y) <- "double"
identical(x,y)
[1] FALSE
> identical(as.double(x),y)
[1] TRUE
Аргумент "double"
обрабатывается как частный случай с помощью as
и будет пытаться принуждать к классу numeric
, который уже наследует класс integer
, поэтому изменений нет.
is.numeric(x)
[1] TRUE
Не так быстро...
В то время как вышеизложенное имело смысл, есть еще одна путаница. Из ?double
:
Это историческая аномалия, что R имеет два имени для своей плавающей точки векторы, двойные и числовые (и ранее были реальные).
double - это имя типа. numeric - это название режима и также неявного класса. В качестве формального класса S4 используйте "числовые".
Потенциальная путаница заключается в том, что R использовал режим "числовой" для обозначения 'Double или integer, что противоречит использованию S4. таким образом is.numeric проверяет режим, а не класс, но as.numeric(который идентичный as.double) принуждает к классу.
Поэтому as
должен действительно изменить x
в соответствии с документацией... Я буду исследовать далее.
Участок толще, чем взбитые сливки и суп из кукурузной муки...
Хорошо, если вы debug
as
, вы узнаете, что в конечном итоге происходит то, что создается следующий метод, а не с использованием подписи c ( "ANY", "numeric" ) для coerce
generic, которая вызовет as.numeric
:
function (from, strict = TRUE)
if (strict) {
class(from) <- "numeric"
from
} else from
Итак, class<-
вызывается на x
, и это означает, что R_set_class
вызывается из coerce.c
. Я считаю, что следующая часть функции определяет поведение:
...
else if(!strcmp("numeric", valueString)) {
setAttrib(obj, R_ClassSymbol, R_NilValue);
if(IS_S4_OBJECT(obj)) /* NULL class is only valid for S3 objects */
do_unsetS4(obj, value);
switch(TYPEOF(obj)) {
case INTSXP: case REALSXP: break;
default: PROTECT(obj = coerceVector(obj, REALSXP));
nProtect++;
}
...
Обратите внимание на оператор switch: он вырывается без принуждения в случае целых чисел и реальных значений.
Ошибка или нет?
Является ли это ошибкой, зависит от вашей точки зрения. Целые числа в одном смысле, как подтверждено is.numeric(x)
возвращением TRUE
, но, строго говоря, они не являются числовым классом. С другой стороны, поскольку целые числа получают возможность автоматически удваиваться при переполнении, можно концептуально их рассматривать как одно и то же. Существуют два основных отличия: i) Целые числа требуют меньше места для хранения - это может быть значительным для больших векторов, и, ii) при взаимодействии с внешним кодом, который имеет более высокие затраты на перераспределение дисциплины, может вступить в игру.