Как правильно использовать списки в R?
Краткая предыстория: Многие (большинство?) Современные языки программирования в широком распространении имеют по крайней мере несколько общих ADT [абстрактных типов данных], в частности,
строка (последовательность, состоящая из символов)
список (упорядоченная коллекция значений) и
тип на основе карты (неупорядоченный массив, который сопоставляет ключи со значениями)
В языке программирования R первые два реализованы какcharacter
а такжеvector
соответственно.
Когда я начал изучать R, две вещи были очевидны почти с самого начала:list
является наиболее важным типом данных в R (потому что это родительский класс для Rdata.frame
) а во-вторых, я просто не могЯ не понимаю, как они работают, по крайней мере, недостаточно хорошо, чтобы правильно использовать их в моем коде.
С одной стороны, мне казалось, что Rlist
Тип данных был простой реализацией карты ADT (dictionary
в Python,NSMutableDictionary
в цели C,hash
в Perl и Ruby,object literal
в Javascript и т. д.).
Например, вы создаете их так же, как словарь Python, передавая пары ключ-значение в конструктор (который в Pythondict
неlist
):
x = list("ev1"=10, "ev2"=15, "rv"="Group 1")
И вы получаете доступ к элементам R List точно так же, как и к словарю Python, например,x['ev1']
, Кроме того, вы можете получить толькоклавиши или простоценности' от:
names(x) # fetch just the 'keys' of an R list
# [1] "ev1" "ev2" "rv"
unlist(x) # fetch just the 'values' of an R list
# ev1 ev2 rv
# "10" "15" "Group 1"
x = list("a"=6, "b"=9, "c"=3)
sum(unlist(x))
# [1] 18
но Rlist
с такжеВ отличие от другие ADT типа карты (из числа языков I 'все равно научились). Я предполагаю, что это является следствием первоначальной спецификации для S, то есть намерения разработать DSL для данных / статистики с нуля.
три значительные различия между Rlist
s и типы отображения в других языках в широком распространении (например, Python, Perl, JavaScript):
первый,list
S в R являютсяприказал коллекции, как и векторы, даже если значения являются ключевыми (т. е. ключи могут быть любыми хешируемыми значениями, а не только последовательными целыми числами). Почти всегда тип данных отображения в других языкахнеупорядоченный.
во-вторых,list
s могут быть возвращены из функций, даже если вы никогда не переходили вlist
когда вы вызвали функцию, идаже если функция, которая вернулаlist
Безразлично»не может содержать (явный)list
Конструктор (Конечно, вы можете справиться с этим на практике, обернув возвращаемый результат в вызовunlist
М):
x = strsplit(LETTERS[1:10], "") # passing in an object of type 'character'
class(x) # returns 'list', not a vector of length 2
# [1] list
в третьих особенность R'slist
s: это неКажется, что они могут быть членами другого ADT, и если вы попытаетесь это сделать, то основной контейнер будет приведен кlist
, Например.,
x = c(0.5, 0.8, 0.23, list(0.5, 0.2, 0.9), recursive=TRUE)
class(x)
# [1] list
мое намерение здесь не состоит в том, чтобы критиковать язык или как это задокументировано; Точно так же яЯ не предполагаю, что сlist
структура данных или как она себя ведет. Все яПосле исправления я понимаю, как они работают, поэтому я могу правильно использовать их в своем коде.
Вот такие вещи яхотелось бы лучше понять:
Какие правила определяют, когда вызов функции вернетlist
(например.,strsplit
выражение, изложенное выше)?
Если я нет явно назначить имена дляlist
(например.,list(10,20,30,40)
) являются ли имена по умолчанию просто последовательными целыми числами, начинающимися с 1? (Я предполагаю, но я далеко не уверен, что ответ да, иначе мы бы нене сможет заставить этот типlist
к вектору с вызовомunlist
.)
Почему эти два разных оператора,[]
, а также[[]]
, вернутьтак же результат?
x = list(1, 2, 3, 4)
оба выражения возвращают «1»:
x[1]
x[[1]]
почему эти два выраженияне вернуть тот же результат?
x = list(1, 2, 3, 4)
x2 = list(1:4)
Пожалуйста, не't указывает мне на документацию R (,?list
R-intro
) - Я внимательно прочитал его, и это не помогает мне ответить на тип вопросов, которые я изложил чуть выше.
(наконец, я недавно узнал о и начал использовать пакет R (доступный в CRAN) под названиемhash
который реализуетобычный поведение типа карты через класс S4; Я, конечно, могу рекомендовать этот пакет.)