如何确定R中类似列表的对象,即使是空的?
我有不同的可能输入值,我想将它们分成两组,一组包含单个/atomar项,另一组包含多个项或空的类似列表的结构 例如,取以下值:如何确定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组合,但是我从来
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