Как вы проверяете скаляр в R?
Мне интересно идентифицировать числовые скаляры вроде:
doub <- 3.14
intg <- 8L
Я знаю, что они рассматриваются как длина одного вектора. Таким образом, для любого объекта R x
, является is.vector(x) && length(x) == 1
правильным способом проверить, является ли x
скаляром? length(x) == 1
сам по себе недостаточно, поскольку возвращает true, когда он должен возвращать false, для фрейма данных с одним столбцом или списком с одним элементом.
Есть ли причина, почему такая функция is.scalar
не реализована в базе R
? По некоторым причинам два случая, которые я мог найти в других функциях, не выполняются для случая фрейма данных, упомянутого ранее, это:
assertthat::is.scalar(data.frame(a = 1:2))
lambda.tools::is.scalar(data.frame(a = 1:2))
Почему результаты этих двух вызовов функций отличаются от моего понимания (и определения) того, как должна работать функция is.scalar
?
Ответы
Ответ 1
Я думаю, что is.atomic
соответствует вашим потребностям.
Для чего is.vector
, вероятно, несовместимо, см., например:
is.atomic(list(1))
# [1] FALSE
is.vector(list(1))
# [1] TRUE
На ваших объектах:
is.scalar <- function(x) is.atomic(x) && length(x) == 1L
is.scalar(doub)
# [1] TRUE
is.scalar(intg)
# [1] TRUE
is.scalar(c(doub, intg))
# [1] FALSE
Ответ 2
Основываясь на ответе на @MichaelChirico, есть еще пара вещей, которые должен проверять is.scalar()
.
Во-первых, комплексные числа обычно не рассматриваются как скаляры (хотя я думаю, что это использование может варьироваться в зависимости от дисциплин).
comp <- 2+3i
is.scalar <- function(x) is.atomic(x) && length(x) == 1L
is.scalar(comp)
# TRUE
поэтому мы должны также проверить комплексные числа. Простой, но наивный способ сделать это - использовать is.complex
is.scalar <- function(x) is.atomic(x) && length(x) == 1L && !is.complex(x)
is.scalar(comp)
# FALSE
К сожалению, это не совсем правильно, потому что is.complex
просто проверяет, является ли класс "complex"
. Но действительные числа могут иметь класс = комплекс, если их мнимая компонента равна нулю.
is.complex(2+0i)
# [1] TRUE
Итак, для проверки реальных чисел нам лучше проверить, что мнимая компонента равна нулю, используя Im(x)==0
. Итак, это приводит нас к проверке скаляров, которые выглядят так:
is.scalar <- function(x) is.atomic(x) && length(x) == 1L && Im(x)==0
Более тривиально, символы также должны быть устранены
is.scalar("x")
# TRUE
is.scalar <- function(x) is.atomic(x) && length(x) == 1L && !is.character(x) && Im(x)==0
is.scalar("x")
# FALSE
Обратите внимание, что мы тестируем для is.character(x)
до Im(x)==0
, чтобы ленивая оценка гарантировала, что функция никогда не пытается найти мнимую составляющую символа, которая выдавала бы ошибку.