如何确定R中类似列表的对象,即使是空的?

如何确定R中类似列表的对象,即使是空的?,r,R,我有不同的可能输入值,我想将它们分成两组,一组包含单个/atomar项,另一组包含多个项或空的类似列表的结构 例如,取以下值: 123 "foo" c() c(c()) list() list(list()) c(1, 2, 3) c("a", "b", "c") c(c("a", 1), "b", "c") list("foo", "bar", c("baz", "blah")) 前两个应归入A类,其余应归入B类 我尝试过各种各样的is.recursive或is.atomic组合,但是我从来

我有不同的可能输入值,我想将它们分成两组,一组包含单个/atomar项,另一组包含多个项或空的类似列表的结构

例如,取以下值:

123
"foo"
c()
c(c())
list()
list(list())
c(1, 2, 3)
c("a", "b", "c")
c(c("a", 1), "b", "c")
list("foo", "bar", c("baz", "blah"))
前两个应归入A类,其余应归入B类

我尝试过各种各样的
is.recursive
is.atomic
组合,但是我从来没有得到正确的分割,例如
123
c(1)
都被认为是原子的、数值的和长度为1的向量

我创建了不同逻辑测试的概览表,但似乎找不到前两行与其他行的区别:

我是否遗漏了一些明显的东西,比如一些可以帮助我更好地区分这些类的属性

复制表格的代码: (类别除外)


types根据@loki的提示,我找到了一个适合我的解决方案:

if (is.null(x) || is.list(x) || (is.vector(x) && (length(x) > 1))) {
    print("Category B")
} else {
    print("Category A")
}
这将产生:

0                                     # => "Option A"
123                                   # => "Option A"
"foo"                                 # => "Option A"
c(1)                                  # => "Option A"
c()                                   # => "Option B"
c(c())                                # => "Option B"
list()                                # => "Option B"
list(list())                          # => "Option B"
c(1, 2, 3)                            # => "Option B"
c("a", "b", "c")                      # => "Option B"
c(c("a", 1), "b", "c")                # => "Option B"
list("foo", "bar", c("baz", "blah"))  # => "Option B"

值得注意的是,
c(1)==1
,并阅读帮助。

您可以使用
length()
is.vector()
is.null()


类型不会
c(1)
也属于A类?嗯,我没有意识到
c(1)
1
完全相同(R内部结构很奇怪)。如果是这样的话,那么这也是类别A,是的。好吧,那么答案将是
length()
is.vector()
is.null()
(因为
is.null(c())
返回一个
TRUE
)的组合。是的,通过在R中设计,即使长度为1的整数也是向量。我认为这是一个有趣的问题。但是,您应该了解R中正确的对象术语,因为它与其他语言不同。也许对未来的游客来说,Q更有用。你可以开始。
0                                     # => "Option A"
123                                   # => "Option A"
"foo"                                 # => "Option A"
c(1)                                  # => "Option A"
c()                                   # => "Option B"
c(c())                                # => "Option B"
list()                                # => "Option B"
list(list())                          # => "Option B"
c(1, 2, 3)                            # => "Option B"
c("a", "b", "c")                      # => "Option B"
c(c("a", 1), "b", "c")                # => "Option B"
list("foo", "bar", c("baz", "blah"))  # => "Option B"
types <- list(123, "foo", c(), c(c()), list(), list(list()), c(1), c(1, 2, 3), c("a", "b", "c"), c(c("a", 1), "b", "c"), list("foo", "bar", c("baz", "blah")))
data.frame(types = paste(types), 
           is.recursive = sapply(types, is.recursive), 
           is.atomic = sapply(types, is.atomic), 
           is.character = sapply(types, is.character), 
           is.numeric = sapply(types, is.numeric), 
           is.vector = sapply(types, is.vector), 
           is.list = sapply(types, is.list), 
           length = sapply(types, length), 
           is.null = sapply(types, is.null), 
           typeof = sapply(types, typeof), 
           class = sapply(types, class), 

           # and now let's get to the mystery using 4 of these values:
           category = sapply(types, function(x){
             ifelse(is.null(x) || is.list(x) || (is.vector(x) && length(x) > 1), "B", "A")
           })) 
#                                  types ... category
#1                                   123 ...        A
#2                                   foo ...        A
#3                                   c() ...        B
#4                                c(c()) ...        B
#5                                list() ...        B
#6                          list(list()) ...        B
#7                                  c(1) ...        A
#8                            c(1, 2, 3) ...        B
#9                      c("a", "b", "c") ...        B
#10                c("a", "1", "b", "c") ...        B
#11 list("foo", "bar", c("baz", "blah")) ...        B