Сп

Списки у R

1 вправа

Про концепцію Списки

list у R - це впорядкована колекція елементів, яка відрізняється від vectors кількома особливостями:

  • Елементи можуть мати різні типи (наприклад, поєднувати numeric з character).
  • Елементи можуть бути складними структурами (наприклад, векторами, іншими списками тощо).
  • Для доступу до елементів використовується дещо інший синтаксис.

Аналогії з іншими мовами неточні. list у R дещо схожий на словник у Python, але він упорядкований, і доступ до нього можна отримати за числовим індексом. Він також дещо схожий на struct у C, але list можна легко розширити під час виконання.

Створення списків

Давати елементам імена (їх часто називають «тегами») у списках доводиться частіше, ніж у векторах:

list(x = 5.3, y = 4.2, color = "blue")
#> $x
#> [1] 5.3

#> $y
#> [1] 4.2

#> $color
#> [1] "blue"

Однак теги необовʼязкові, і тоді R просто використає порядкові номери:

list(5.3, 4.2, "blue")
#> [[1]]
#> [1] 5.3

#> [[2]]
#> [1] 4.2

#> [[3]]
#> [1] "blue"

Доступ до елементів списку

Є три способи це зробити, і кожен із них зручний у різних ситуаціях.

1. Через запис $tag

Дуже поширений, якщо назви тегів відомі заздалегідь.

point <- list(x = 5.3, y = 4.2, color = "blue")
#> point$x
#> [1] 5.3
#> point$color
#> [1] "blue"

2. Через запис [[tag]]

Його перевага в тому, що назву тега можна вибрати під час виконання. Звернімо увагу на подвійні дужки.

want <- "y"
point[[want]] # same as point$y
#> [1] 4.2

3. За порядковим індексом

Це працює незалежно від того, чи має список теги. Тут також подвійні дужки.

point[[3]] # same as point$color
#> [1] "blue"

Додавання та видалення елементів

Усе просто: присвоєння елементу змінить його, якщо він існує, або додасть, якщо він новий.

point$color <- "red"
point$trust <- TRUE

# str() gives more compact output than the default display
str(point) 
#> List of 4
#>  $ x    : num 5.3
#>  $ y    : num 4.2
#>  $ color: chr "red"
#>  $ trust: logi TRUE

Щоб видалити елемент, присвоймо NULL непотрібному елементу.

point$trust <- NULL
str(point)  
#> List of 3
#>  $ x    : num 5.3
#>  $ y    : num 4.2
#>  $ color: chr "red"

Списки - це «рекурсивні вектори»

Клас vector технічно називають atomic vector, бо він може містити лише атомарні значення: numeric, character, boolean тощо. Оскільки list може містити інші списки, його ще називають recursive vector.

Окрім суто термінологічного нюансу, це нагадування про те, що списки можуть мати довільно складну структуру. Відповідальність програміста - розуміти, що саме буде надано під час доступу до елемента списку.

Докладніше про індексацію списків

У деяких прикладах вище для доступу до елементів списку використано подвійні дужки [[ ]]. Це намагається звести елемент до його базового типу, що зручно, якщо потрібне просто число або рядок тексту (англ. string).

Одинарні дужки [ ] такого зведення не роблять, і повернене значення буде підсписком.

point[["color"]]
#> [1] "red"  # flattened

point["color"]
#> $color
#> [1] "red"  # sublist

Навіть якщо підсписок - не те, чого, найімовірніше, хоче програміст-початківець у R, варто про це знати. Задля максимальної гнучкості багато стандартних функцій R повертають list, навіть коли він містить єдине атомарне значення, як тут.

Щоб перетворити його на вектор, є два варіанти.

  1. Взяти перший елемент через [[1]]
  2. Скористатися функцією unlist().
pt <-point["color"]

pt[[1]]
#> [1] "red" # simple 1-element vector

unlist(pt)
#> color 
#> "red"  # 1-element vector with name

Будьмо обережні з unlist(). Зведення структури корисне в цьому простому випадку, але може спричинити несподіванки зі складнішими елементами списку.

Advanced

Внутрішнє представлення

list, як і атомарний vector, зберігається неперервно. Різниця в тому, що числові та булеві вектори зберігають значення, а список зберігає посилання на обʼєкти, розташовані в інших ділянках памʼяті.

Знання цього рідко буває важливим для користувача R, але в такій багатомовній спільноті, як Exercism, воно може стати в пригоді програмістам, знайомим з іншими мовами.

Редагувати через GitHub Посилання відкривається в новому вікні або вкладці

Вивчити концепцію Списки