Списки в програмуванні на R: Як створювати та вибирати елементи

⚡ Розумний підсумок

R List – це об'єкт, який зберігає вектори, матриці, фрейми даних та навіть інші списки в одному контейнері. Функція list() його створює, а подвійні квадратні дужки витягують будь-який елемент назад.

  • 🧺 Змішане сховище: Список містить об'єкти різних типів та довжин, чого не може зробити звичайний вектор.
  • 🛠️ Крок складання: list(vect, mat, df) об'єднує вектор, матрицю та фрейм даних в один об'єкт.
  • 🔢 Доступ до посади: my_list[[2]] повертає сам елемент, тоді як my_list[2] повертає список з одного елемента.
  • 🏷️ Іменовані елементи: Позначення елементів тегами під час створення дозволяє доступ до них через оператор $ або [[“name”]].
  • ✏️ Редагування на місці: Перепризначення оновлює елемент, а присвоєння NULL видаляє його зі списку.
  • 🔗 Зведення: unlist() згортає вкладений список в один атомарний вектор для подальшого аналізу.

Список R Створення списку в програмуванні на R та вибір елементів

Що таке R List?

R Список це об’єкт у програмуванні R, який містить матриці, вектори, кадри даних або списки всередині нього. R List також використовується для зберігання колекції об’єктів і використання їх, коли вони нам потрібні. Ми можемо уявити список R як мішок, куди можна помістити багато різних предметів. Коли нам потрібно використати предмет, ми можемо відкрити сумку та використати його.

Контраст із вектором робить сумку корисною. Вектор примушує кожен елемент до одного типу, тому розміщення слова поруч із числом перетворює число на текст. Список не застосовує такого правила, тому він може містити вектор із п'яти елементів, дворядковий матриця і фрейм даних із 714 рядків поруч, не змінюючи жодного з них.

Синтаксис списку в R

Ми можемо використовувати функцію list() для створення списків у програмуванні на R:

list(element_1, ...)
arguments:
-element_1: store any type of R object
-...: pass as many objects as specifying. each object needs to be separated by a comma

Кожен аргумент може бути переданий як у чистому вигляді, так і у формі тег = значенняГолий аргумент стає позиційним елементом, досяжним лише за його номером, тоді як тегований аргумент також отримує назву. Базове посилання R для список () документує як форми, так і зазначає, що unlist() діє як приблизний зворотний механізм as.list().

Як створити список у R

Нижче наведено крок за кроком процес створення списку в R:

У наведеному нижче прикладі ми створимо три різні об’єкти: вектор, матрицю та a Кадр даних за допомогою функції списку в R.

Крок 1) Створіть вектор

Використовуйте наведений нижче код, щоб створити вектор у R

# Vector with numeric from 1 up to 5
vect  <- 1:5

Оператор двокрапки будує послідовність 1, 2, 3, 4, 5 як цілочисельний вектор, а стрілка присвоєння зберігає його під іменем vect.

Крок 2) Створіть матрицю

Тепер створіть матрицю, використовуючи наступний код

# A 2x 5 matrix
mat  <- matrix(1:9, ncol = 5)
dim(mat)

Тут варто звернути увагу на дві деталі. Сітка з двох рядків на п'ять стовпців потребує десяти значень, проте надається лише дев'ять, тому R переробляє послідовність і виводить попередження про те, що довжина даних не є частиною кратної кількості рядків. Це перероблене значення є причиною того, що другий рядок надрукованої матриці закінчується на 1, а не на 10. Виклик dim() потім повідомляє про форму.

вихід:

## [1] 2 5

Крок 3) Створіть фрейм даних

Створіть кадр даних у R, використовуючи наведений нижче код

# select the 10th row of the built-in R data set EuStockMarkets
df <- EuStockMarkets[1:10,]

У коментарі згадується десятий рядок, але вираз зберігає рядки з 1 по 10 вбудованого ряду EuStockMarkets. Підмноження також видаляє клас часового ряду, тому повертається числова матриця, а не справжній фрейм даних, саме тому наведений нижче результат містить мітки рядків у стилі [1,] замість імен рядків. Обгорніть виклик у as.data.frame() щоразу, коли потрібен справжній фрейм даних.

Крок 4) Створіть список у R

Тепер ми можемо помістити ці три об’єкти в список R, використовуючи наведений нижче код

# Construct list with these vec, mat, and df:
my_list <- list(vect, mat, df)
my_list

вихід:

## [[1]]
## [1] 1 2 3 4 5

## [[2]]
##       [,1] [,2] [,3] [,4] [,5]
## [1,]    1    3    5    7    9
## [2,]    2    4    6    8    1

## [[3]]
##          DAX    SMI    CAC   FTSE
##  [1,] 1628.75 1678.1 1772.8 2443.6
##  [2,] 1613.63 1688.5 1750.5 2460.2
##  [3,] 1606.51 1678.6 1718.0 2448.2
##  [4,] 1621.04 1684.1 1708.1 2470.4
##  [5,] 1618.16 1686.6 1723.1 2484.7
##  [6,] 1610.61 1671.6 1714.3 2466.8
##  [7,] 1630.75 1682.9 1734.5 2487.9
##  [8,] 1640.17 1703.6 1757.4 2508.4
##  [9,] 1635.47 1697.5 1754.0 2510.5
##  [10,] 1645.89 1716.3 1754.3 2497.4

Три заголовки у подвійних квадратних дужках у цьому виводі – це позиції списку. Нічого не було зведено до мінімуму чи примусово змінено: елемент один все ще є цілочисельним вектором, елемент два – матрицею, а елемент третій все ще містить усі десять рядків цін на акції.

Виберіть елементи зі списку R

Після того, як ми створили наш список, ми можемо досить легко отримати до нього доступ. Нам потрібно використовувати [[index]] для вибору елемента у списку. Значення всередині подвійної квадратної дужки представляє позицію елемента у списку, який ми хочемо переглянути.tracт. Наприклад, ми передаємо 2 всередині дужок, R повертає другий елемент зі списку.

Тепер у цьому R підручник, давайте спробуємо вибрати другі елементи списків у R з назвою my_list, ми використовуємо my_list[[2]]

# Print second element of the list
my_list[[2]]

вихід:

##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    3    5    7    9
## [2,]    2    4    6    8    1

Одинарні та подвійні дужки не є взаємозамінними, і їх плутанина є найпоширенішою причиною помилок у списку. Одна дужка зберігає обгортку, дві дужки її видаляють.

вираз Що повертається Клас результату Використовуйте його, коли
мій_список[[2]] Сам збережений елемент Що б там не зберігалося, ось матриця Вам потрібно обчислити на основі одного елемента
мій_список[2] Підсписок, що містить цей один елемент список Вам потрібно зберегти обгортку списку
мій_список[c(1, 3)] Підсписок вибраних елементів список Вам потрібно кілька елементів одночасно
мій_список[-2] Кожен елемент, крім другого список Вам потрібно скинути елемент
# Compare the two bracket styles
class(my_list[[2]])   # the matrix itself
class(my_list[2])     # a list of length one

# Several elements, and everything but one element
my_list[c(1, 3)]
my_list[-2]

Іменовані списки в R

Позиційні індекси є крихкими: вставляйте один елемент і кожне число після нього зсувається. Іменування елементів усуває цей ризик і робить код читабельним як дані, які він описує. Імена можна вказати під час побудови списку або додавати пізніше за допомогою names().

# Tag each element at creation time
named_list <- list(numbers = vect, grid = mat, prices = df)

# Three ways to reach the same element
named_list$grid
named_list[["grid"]]
named_list["grid"]      # returns a one-element list

# Read or replace the names later
names(named_list)
names(named_list)[2] <- "grid_2x5"

Оператор $ та подвійна дужка відрізняються в одному аспекті, який підводить новачків. Оператор $ виконує часткове зіставлення, тому named_list$pri все ще знаходить ціни, тоді як named_list[[“pri”]] повертає NULL, оскільки подвійні дужки точно збігаються, якщо не передано exact = FALSE. Часткове зіставлення зручне в консолі та небезпечне в скрипті, тому надайте перевагу точній формі в збереженому коді.

# A compact map of the whole structure
str(named_list)

str() друкує один рядок для кожного елемента з його типом та розміром, що є найшвидшим способом перевірити, чи список містить очікувані значення, перш ніж індексувати його.

Зміна, додавання та видалення елементів у списку R

Список не є фіксованим після створення. Ті самі аксесори, які читають елемент, також записують у нього значення, тому оновлення, розширення та стиснення списку використовують звичайне присвоєння.

# Replace an element in place
named_list[["numbers"]] <- 1:10

# Add a new element simply by naming it
named_list[["created"]] <- Sys.Date()

# Append without a name: the element lands at the end
named_list <- append(named_list, list(TRUE))

# Delete an element by assigning NULL to it
named_list[["created"]] <- NULL
  • Замінити: Присвоєння існуючому імені перезаписує цей елемент і залишає його позицію незмінною.
  • Додати: присвоєння імені, яке не існує, додає новий елемент у кінець списку.
  • Додайте: append() приймає список як другий аргумент, тому перед передачею значення в list() його потрібно обгорнути.
  • Видалити: Присвоєння значення NULL з подвійними дужками видаляє елемент і скорочує список.

Один наслідок регулярно ставить людей у ​​глухий кут: оскільки NULL означає видалення, ви не можете зберігати фактичне NULL за допомогою подвійних дужок. Натомість використовуйте присвоєння з одинарними дужками, як у named_list[“empty”] <- list(NULL), що зберігає слот і поміщає NULL всередині нього.

Вкладені списки та unlist() в R

Оскільки список може містити будь-який об'єкт R, він може містити інший список. Вкладеність — це те, як об'єкти конфігурації, відповіді JSON та результати моделі зазвичай представлені в R, тому доступ до вкладеного списку та його вирівнювання є щоденними завданнями.

# A list whose elements are themselves lists
project <- list(
  meta = list(owner = "analyst", year = 2026),
  data = list(vect, mat)
)

# Chain the accessors to reach an inner value
project$meta$year
project[["data"]][[2]]

# Flatten every level into one atomic vector
flat <- unlist(project)

# Strip a single level and keep the rest as a list
half <- unlist(project, recursive = FALSE)

Зведення до меншого має свою ціну, яку варто зрозуміти. unlist() має повертати один атомарний вектор, тому він приводить кожне значення до найзагальнішого типу, що є в наявності, дотримуючись порядку logical, integer, double, character. Вкладений список, який змішує числа з текстом, таким чином, повертається повністю як текст. Назви результату створюються шляхом об'єднання зовнішніх та внутрішніх тегів, тому елемент надходить як meta.owner, а не owner.

Передайте use.names = FALSE, якщо ці складені імена небажані, та встановіть recursive = FALSE, якщо потрібно видалити лише найзовніший шар. Якщо значення мають зберегти свої типи, залиште структуру недоторканою та пройдіться по списку, замість того, щоб згладжувати його.

Вбудований фрейм даних у R

Списки часто заповнюються даними, що зчитуються з диска або з Інтернету, тому корисно побачити, як фрейм даних надходить, перш ніж він зберігається всередині нього. Перш ніж створювати власний фрейм даних, ми можемо переглянути набір даних R, доступний онлайн. Набір даних в'язниці має розмір 714×5. Ми можемо швидко переглянути нижню частину фрейму даних за допомогою функції tail(). За аналогією, head() відображає верхню частину фрейму даних. Ви можете вказати кількість відображаних рядків за допомогою head(df, 5). Ми дізнаємося більше про функцію read.csv() у імпортувати дані в R навчальний посібник.

PATH <-'https://raw.githubusercontent.com/guru99-edu/R-Programming/master/prison.csv'
df <- read.csv(PATH)[1:5]
head(df, 5)

вихід:

##   X state year govelec black
## 1 1     1   80       0 0.2560
## 2 2     1   81       0 0.2557
## 3 3     1   82       1 0.2554
## 4 4     1   83       0 0.2551
## 5 5     1   84       0 0.2548

[1:5], що йде після read.csv(), вибирає перші п'ять стовпців, а не перші п'ять рядків, оскільки фрейм даних сам по собі є списком стовпців. Індексація списку в одинарних дужках повертає менший список, і тут цей менший список все ще є фреймом даних.

Ми можемо перевірити структуру кадру даних за допомогою str:

# Structure of the data
str(df)

вихід:

## 'data.frame':    714 obs. of  5 variables:
##  $ X      : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ state  : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ year   : int  80 81 82 83 84 85 86 87 88 89 ...
##  $ govelec: int  0 0 1 0 0 0 1 0 0 0 ...
##  $ black  : num  0.256 0.256 0.255 0.255 0.255 ...

Усі змінні зберігаються в числовий формат. Префікс $ у кожному рядку — це той самий оператор, що використовувався раніше у іменованих списках, що підтверджує, що фрейм даних — це список стовпців однакової довжини з прямокутною міткою. Тому все, що ми дізналися про іменування, вибір та видалення елементів списку, безпосередньо переноситься до Типи даних R і до стовпців фрейму даних.

Поширені запитання

Вектор змушує кожен елемент використовувати один спільний тип, тому змішування тексту та чисел призводить до перетворення всього на символ. Список зберігає кожен елемент точно так, як його надано, включаючи вектори, матриці та функції різної довжини. Використовуйте typeof(), щоб розрізнити їх.

Викличте is.list(x), яка повертає TRUE для списків та парних списків. class(x) повідомляє клас об'єкта, тоді як typeof(x) повертає «list» навіть для фреймів даних, оскільки фрейм даних – це список стовпців однакової довжини під ним.

length(my_list) враховує лише елементи верхнього рівня, тому вкладений список все одно враховується як один. lengths(my_list) повертає розмір кожного елемента в одному виклику, що швидше та зрозуміліше, ніж loo.ping коли елементи відрізняються.

lapply(my_list, FUN) застосовує функція до кожного елемента та повертає список. sapply() спрощує результат до вектора або матриці, де це можливо. Простий цикл for поверх seq_along(my_list) також працює та читається зрозуміло.

Коли кожен елемент має однакову довжину, as.data.frame(my_list) працює безпосередньо. Для списку рядків однакової ширини, do.call(rbind, my_list) спочатку складає їх у стек. dplyr екосистема пропонує as_tibble(), коли типи стовпців повинні залишатися недоторканими.

Списки не мають вбудованого сортування, тому extracСпочатку порівняльний ключ: my_list[order(sapply(my_list, length))] перевпорядковує за розміром елемента. Для прямокутних даних конвертує у фрейм та сортувати фрейм даних з order() замість цього.

Асистенти ШІ читають вивід str() і пояснюють, чому індекс повернув NULL або підсписок замість значення. Вони також пропонують правильну форму дужок, проектують конвеєри lapply() та позначають тихе приведення типів, перш ніж воно пошкодить результат.

Так. Копілот GitHub працює в RStudio 2023.09.0 та пізніших версій через Інструменти, Глобальні параметри, а потім налаштування помічника коду. Він завершує виклики list(), names() та unlist() з коментаря, хоча кожна пропозиція все одно потребує перевірки.

Підсумуйте цей пост за допомогою: