2016-06-29 31 views
10

我对标识等数字标量:你如何检查R中的标量?

doub <- 3.14 
intg <- 8L 

我知道,这些都是作为一个长度矢量处理。因此,对于任何R对象x,是is.vector(x) && length(x) == 1正确的方法来检查x是否是标量? length(x) == 1本身是不够的,因为它返回一个真正的,当它应该返回false时,对于具有一列的数据帧或具有一个元素的列表。

有没有这样的功能is.scalar在基地执行R?出于某种原因,这两个我能找到在其他功能失败前面提到的数据帧的情况下,它们是:

assertthat::is.scalar(data.frame(a = 1:2)) 
lambda.tools::is.scalar(data.frame(a = 1:2)) 

为什么这两个函数的结果如何调用不同的,以我的理解(和定义) is.scalar函数应该工作吗?

+2

你可能想'is.atomic'而不是'is.vector'。 –

+2

两者有什么区别? – Alex

+0

请参阅'?is.atomic':“通常调用原子类型的原子向量,但请注意”是“。矢量“进一步限制:一个对象可以是原子,但不是矢量(从这个意义上说)。” – MichaelChirico

回答

8

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

建立在answer通过@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 

请注意,我们Im(x)==0让懒惰的评价确保之前测试is.character(x)该函数从来不会试图找到一个字符的虚构成分,这会引发错误。

+0

那么为什么不简单地使用'is.scalar < - function(x)length(x)== 1L && is.vector(x,mode =“numeric”)'? – Wastl

+1

@Wastl它取决于你想要测试的目的和实例,但是使用你的定义'is.scalar(x)'会失败。 'x = 1 + 0i','x = NA'和'x = 1; attr(x,'foo')= 1' – dww