我感兴趣的是识别数字标量:
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
函数应该如何工作的理解(和定义)不同?
答案 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
就足够了。