你如何检查R中的标量?

时间:2016-06-29 00:28:22

标签: r

我感兴趣的是识别数字标量:

doub <- 3.14
intg <- 8L

我知道这些被视为长度为一的向量。因此,对于任何R对象xis.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函数应该如何工作的理解(和定义)不同?

3 个答案:

答案 0 :(得分:10)

我认为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

答案 1 :(得分:8)

在@MichaelChirico的answer的基础上,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"。但如果实数为零,则实数可以为class = 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,以便延迟评估确保函数永远不会尝试查找字符的虚构组件,这会引发错误。

答案 2 :(得分:0)

一个复数当然是一个标量,它是一个数字。 因此,is.scalar <- function(x) is.atomic(x) && length(x) == 1L就足够了。