В чем разница между [[]] и $в индексировании списка?

Может ли кто-нибудь объяснить, почему list1 и list2 ниже не идентичны?

list1 <- list()
lev1 <- "level1"
lev2 <- "level2"
list1[[lev1]][[lev2]] <- 1
list1
$level1
level2 
     1 

list2 <- list()
list2$level1$level2 <- 1
list2
$level1
$level1$level2
[1] 1

Ответы

Ответ 1

Это происходит потому, что вы назначаете вектор длины 1 NULL-атомному вектору.

От help(Extract) -

Когда $<- применяется к NULL x, он сначала принуждает x к list(). Это также происходит с [[<-, если значение замены value имеет длину больше единицы: если value имеет длину 1 или 0, x сначала принудительно привязывается к вектору нулевой длины типа value.

Измените назначение на ... <- 1:2 (или что-то другое, чем длина 0 или 1 вектор), и вы получите тот же результат в обоих блоках кода.

list1 <- list()
lev1 <- "level1"
lev2 <- "level2"
list1[[lev1]][[lev2]] <- 1:2
list1
# $level1
# $level1$level2
# [1] 1 2

list2 <- list()
list2$level1$level2 <- 1:2
list2
# $level1
# $level1$level2
# [1] 1 2

Более простой пример этого, как уже упоминалось в комментариях @alexis_laz, заключается в том, чтобы начать с NULL атомного вектора и посмотреть, что происходит.

x <- NULL
## assign a length 1 vector --> atomic result
x[["lev1"]] <- 1
x
# lev1 
#    1 

y <- NULL
## assign a length > 1 vector --> list result
y[["lev1"]] <- 1:2
y
# $lev1
# [1] 1 2

Результат из $<- всегда является списком, поэтому я опустил его здесь.