Поэтому, когда вы делаете
l <- list()
l[[index1]][[index2]] <- s
, проблема заключается в том, что l
инициализируется как список, поэтому имеет смысл установить новый именованный элемент с l[[index1]]
, но R не имеет понятиячто хранится в l[[index1]][[index2]]
.Это может быть что угодно.Это может быть функция, и функции не знают, что делать с именованной операцией индексации.Например,
l <- list()
l[[index1]] <- mean
l[[index1]][[index2]] <- "character"
Но в вашем случае, когда вы попытаетесь получить значение из списка, который еще не был инициализирован, вы получите NULL
.Например,
l <- list()
l[[index1]]
# NULL
R имеет особое поведение, когда вы пытаетесь установить именованное атомное значение для объекта NULL.Обратите внимание:
# NULL[["a"]] <- "character" is basically calling....
`[[<-`(NULL, "a", "character")
# a
# "character"
Обратите внимание, что здесь мы получаем именованный вектор.Не списокЭто относится и к вашим «рабочим» примерам
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, вы можете «волшебным образом» оживить хеши с правильным синтаксисом индексации с помощью автовивификации, но это не так в R. Если вы хотите, чтобы list()
существовал в l[[index1]]
, вам нужно явно создать его.Это будет работать
l <- list()
l[[index1]] <- list()
l[[index1]][[index2]] <- s
Опять же, это потому, что [[ ]]
немного двусмысленен в R. Это общая функция индексации, не используемая исключительно со списками.