В R тип integer наследуется от типа «цифра c» или нет? - PullRequest
1 голос
/ 30 января 2020

Я пытаюсь проверить ввод, получаемый от пользователя, чтобы убедиться, что это правильный тип. В этом случае у меня все в порядке с integer или double, если это какое-то число.

Я использую checkmate::check_class() примерно так со следующими результатами:

> checkmate::check_class(4, "numeric")
[1] TRUE
> checkmate::check_class(as.integer(4), "numeric")
[1] "Must inherit from class 'numeric', but has class 'integer'"

Моя путаница заключается в том, что многочисленные источники на inte rnet (в частности, этот от Хэдли, в разделе 12.3.1), похоже, говорят, что и integer, и double do фактически наследуется от numeric. Так почему же это не удается?

Sidenote: check_class() говорит, что он использует inherits() под капотом, поэтому я попытался использовать его явно и получил те же результаты.

> inherits(4, "numeric")
[1] TRUE
> inherits(as.integer(4), "integer")
[1] TRUE
> inherits(as.integer(4), "numeric")
[1] FALSE

Заранее спасибо за любую помощь и разъяснения.

1 Ответ

1 голос
/ 30 января 2020

Это действительно связано с разницей между mode и class. Когда вы используете as.integer(4), вы явно создаете объект класса integer. inherits проверяет наследование класса и поэтому inherits(as.integer(4),"numeric") вернет FALSE, потому что это не класс numeric.

as.integer(4) по-прежнему является numeric объектом, но R inherits проверяет только class, а не mode s, что отличается от того, что вы ожидали бы с точки зрения наследования.

наследует указывает, наследует ли его первый аргумент какой-либо из классов, указанных в аргументе what. Если значение TRUE, то целочисленный вектор такой же длины, что и возвращаемый. Каждый элемент указывает позицию в классе (x), совпадающую с элементом what; ноль означает отсутствие совпадения. Если это ЛОЖЬ, то ИСТИНА возвращается наследниками, если любое из имен совпадает с любым классом.

Теперь, глядя на исходный код checkmate::check_class, он делает то же самое ( проверка наследования класса, а не mode ):

function (x, classes, ordered = FALSE, null.ok = FALSE) 
{
    qassert(classes, "S+")
    qassert(ordered, "B1")
    qassert(null.ok, "B1")
    if (is.null(x) && null.ok) 
        return(TRUE)
    ord = inherits(x, classes, TRUE)
    w = wf(ord == 0L)
    if (length(w) > 0L) {
        cl = class(x)
        return(sprintf("Must inherit from class '%s', but has class%s '%s'", 
            classes[w], if (length(cl) > 1L) "es" else "", 
            paste0(cl, collapse = "','")))
    }

Почему работает первый?

Используйте checkmate :: check_class (4, "Numberri c"), он правильно возвращает TRUE, потому что:

 class(4)
[1] "numeric"

Я думаю, что inheritance здесь не используется так, как вы могли бы ожидать, потому что кажется, что он останавливается на «одном уровне» (только класс, а не режим):

mode(as.integer(4))
[1] "numeric"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...