Извлечение подэлементов из списка списков против списка векторов с помощью lapply - PullRequest
0 голосов
/ 05 ноября 2018

Как lapply извлекает подэлементы из списка? Более конкретно, как lapply извлекает подэлементы из списка списков по сравнению со списком векторов? Более конкретно, предположим, что у меня есть следующее:

my_list_of_lists <- list(list(a = 1, b = 2), list(a = 2, c = 3), list(b = 4, c = 5))
my_list_of_lists[[1]][["a"]] # just checking
# [1] 1 
# that's what I expected

и применить следующее:

lapply(my_list_of_lists, function(x) x[["a"]]) 
# [[1]]
# [1] 1
# 
# [[2]]
# [1] 2
# 
# [[3]]
# NULL

Таким образом, lapply извлекает элемент a из каждого из 3 подсписков, возвращая каждый в своем собственном списке, содержащемся в списке length = 3. На данный момент моя ментальная модель выглядит следующим образом: lapply применяет FUN к каждому элементу my_list, возвращая FUN(my_list[[i]]) для i в 1:3. Большой! Поэтому я ожидаю, что моя ментальная модель должна работать и для списков векторов. Например,

my_list_of_vecs <- list(c(a = 1, b = 2), c(a = 2, c = 3), c(b = 4, c = 5))
my_list_of_vecs[[1]][["a"]] # Just checking
# [1] 1
# that's what I expected

и применять следующее:

lapply(my_list_of_vecs, function(x) x[["a"]]) 
# Error in x[["a"]] : subscript out of bounds
# Wait...What!?

Что здесь происходит? Разве это не должно работать? Я нашел раздел в help(lapply), который может быть актуален:

По историческим причинам вызовы, созданные lapply, не оценены, и код был написан (например, bquote), который опирается на это. это означает, что записанный вызов всегда имеет форму FUN (X [[i]], ...), с заменой на текущий индекс (целое или двойное). Это не обычно проблема, но это может быть, если FUN использует sys.call или match.call или если это примитивная функция, которая использует вызов. это означает, что часто безопаснее вызывать примитивные функции с обертка, так что, например, lapply (ll, функция (x) is.numeric (x)) необходимо убедиться, что метод отправки для is.numeric происходит правильно.

Я действительно не знаю, как это понять.

Я думаю, что это связано с тем фактом, что вы можете использовать извлечение отдельных элементов из вектора как [[, так и [, но вы можете использовать ТОЛЬКО [ извлечение диапазонов элементов. Например,

my_list_of_vecs[[1]][1:2]
# a b 
# 1 2
my_list_of_vecs[[1]][[1:2]]
# Error in my_list_of_vecs[[1]][[1:2]] : 
#   attempt to select more than one element in vectorIndex

Таким образом, под капотом lapply должен использовать function(x) x[["a"]] в диапазоне. Это правильно?

Отладка здесь не помогает, так как эти функции основаны на .Internal функциях.

...