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

时间:2017-12-13 11:55:43

标签: 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.recursiveis.atomic的各种组合,但我从未得到正确的拆分,例如123c(1)都被视为原子,数字,以及长度为1的向量。

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

我是否遗漏了一些明显的东西,比如某些能让我更好地区分这些类的属性?

重现表格的代码:

(类别除外)

types <- list(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")))

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)) 

2 个答案:

答案 0 :(得分:1)

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

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

此外,您应该看看rapportools::is.empty()。但是,它对于嵌套列表(list(list()))失败。

答案 1 :(得分:0)

根据@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和阅读introduction to data structures也有帮助。