将 S4 对象保存在列表列表中
Saving S4 objects in a list of list
当您想将 S4 对象保存到列表的列表中并且该元素之前尚未定义时,R 会给出以下消息错误。
"invalid type/length (S4/0) in vector allocation"
为什么它使用简单的列表,而不是列表的列表?
请参阅以下代码和可能的解决方法。
但是,我很确定有一个更明显的解决方案。
# Creation of an S4 object
setClass("student", slots=list(name="character", age="numeric", GPA="numeric"))
s <- new("student",name="John", age=21, GPA=3.5)
# Indexes for the list
index1 <- "A"
index2 <- "a"
# Simple list (All of this works)
l <- list()
l[[index1]] <- s
l[[index1]] <- "character"
l[[index1]] <- 999
# List of list
l <- list()
l[[index1]][[index2]] <- s # will give an Error!!
l[[index1]][[index2]] <- "character" # still working
l[[index1]][[index2]] <- 999 # still working
# "Workarounds"
l <- list()
l[[index1]][[index2]] <- rep(999, length(slotNames(s))) #define the element with a length equal to the number of slots in the s4 object
l[[index1]][[index2]] <- s # this works now!
l[[index1]][[index2]] <- list(s) # This works too, but that's not the same result
关于为什么它不适用于列表列表以及我如何解决这个问题有什么建议吗?谢谢
所以当你这样做时
l <- list()
l[[index1]][[index2]] <- s
问题是 l
被初始化为一个列表,所以用 l[[index1]]
设置一个新的命名元素是有意义的,但是 R 不知道 [=19= 存储了什么].它可以是任何东西。它可能是一个函数,而函数不知道如何处理命名索引操作。例如
l <- list()
l[[index1]] <- mean
l[[index1]][[index2]] <- "character"
但在您的情况下,当您尝试从尚未初始化的列表中获取值时,您将得到 NULL
。例如
l <- list()
l[[index1]]
# NULL
当您尝试在 NULL 对象上设置命名原子值时,R 恰好有特殊行为。观察
# NULL[["a"]] <- "character" is basically calling....
`[[<-`(NULL, "a", "character")
# a
# "character"
请注意,我们在这里得到一个命名向量。不是清单。您的 "working" 示例也是如此
l <- list()
l[[index1]][[index2]] <- "character"
class(l[[index1]][[index2]])
# [1] "character"
另请注意,这与 S4 没有任何关系。如果我们也尝试像函数一样设置更复杂的对象,也会发生同样的情况
l <- list()
l[[index1]][[index2]] <- mean
# Error in l[[index1]][[index2]] <- mean :
# invalid type/length (closure/0) in vector allocation
在像 Perl 这样的语言中,您可以 "magically" 通过 autovivification 使用正确的索引语法使散列栩栩如生,但在 R 中并非如此。如果您希望 list()
存在在 l[[index1]]
您将需要明确地创建它。这会起作用
l <- list()
l[[index1]] <- list()
l[[index1]][[index2]] <- s
同样,这是因为 [[ ]]
在 R 中有点模棱两可。它是一个通用索引函数,不专门用于列表。
当您想将 S4 对象保存到列表的列表中并且该元素之前尚未定义时,R 会给出以下消息错误。
"invalid type/length (S4/0) in vector allocation"
为什么它使用简单的列表,而不是列表的列表?
请参阅以下代码和可能的解决方法。 但是,我很确定有一个更明显的解决方案。
# Creation of an S4 object
setClass("student", slots=list(name="character", age="numeric", GPA="numeric"))
s <- new("student",name="John", age=21, GPA=3.5)
# Indexes for the list
index1 <- "A"
index2 <- "a"
# Simple list (All of this works)
l <- list()
l[[index1]] <- s
l[[index1]] <- "character"
l[[index1]] <- 999
# List of list
l <- list()
l[[index1]][[index2]] <- s # will give an Error!!
l[[index1]][[index2]] <- "character" # still working
l[[index1]][[index2]] <- 999 # still working
# "Workarounds"
l <- list()
l[[index1]][[index2]] <- rep(999, length(slotNames(s))) #define the element with a length equal to the number of slots in the s4 object
l[[index1]][[index2]] <- s # this works now!
l[[index1]][[index2]] <- list(s) # This works too, but that's not the same result
关于为什么它不适用于列表列表以及我如何解决这个问题有什么建议吗?谢谢
所以当你这样做时
l <- list()
l[[index1]][[index2]] <- s
问题是 l
被初始化为一个列表,所以用 l[[index1]]
设置一个新的命名元素是有意义的,但是 R 不知道 [=19= 存储了什么].它可以是任何东西。它可能是一个函数,而函数不知道如何处理命名索引操作。例如
l <- list()
l[[index1]] <- mean
l[[index1]][[index2]] <- "character"
但在您的情况下,当您尝试从尚未初始化的列表中获取值时,您将得到 NULL
。例如
l <- list()
l[[index1]]
# NULL
当您尝试在 NULL 对象上设置命名原子值时,R 恰好有特殊行为。观察
# NULL[["a"]] <- "character" is basically calling....
`[[<-`(NULL, "a", "character")
# a
# "character"
请注意,我们在这里得到一个命名向量。不是清单。您的 "working" 示例也是如此
l <- list()
l[[index1]][[index2]] <- "character"
class(l[[index1]][[index2]])
# [1] "character"
另请注意,这与 S4 没有任何关系。如果我们也尝试像函数一样设置更复杂的对象,也会发生同样的情况
l <- list()
l[[index1]][[index2]] <- mean
# Error in l[[index1]][[index2]] <- mean :
# invalid type/length (closure/0) in vector allocation
在像 Perl 这样的语言中,您可以 "magically" 通过 autovivification 使用正确的索引语法使散列栩栩如生,但在 R 中并非如此。如果您希望 list()
存在在 l[[index1]]
您将需要明确地创建它。这会起作用
l <- list()
l[[index1]] <- list()
l[[index1]][[index2]] <- s
同样,这是因为 [[ ]]
在 R 中有点模棱两可。它是一个通用索引函数,不专门用于列表。