Списки в языке программирования R: как создавать и выбирать элементы.

⚡ Умное резюме

В R List — это объект, который хранит векторы, матрицы, фреймы данных и даже другие списки в одном контейнере. Функция list() создает его, а двойные квадратные скобки извлекают любой элемент обратно.

  • 🧺 Смешанное хранение данных: Список содержит объекты разных типов и длин, чего не может сделать обычный вектор.
  • 🇧🇷 Этап сборки: Функция `list(vect, mat, df)` объединяет вектор, матрицу и фрейм данных в один объект.
  • 🔢 Доступ к должности: my_list[[2]] возвращает сам элемент, а my_list[2] возвращает список из одного элемента.
  • 🏷️ Именованные элементы: Добавление тегов к элементам при их создании позволяет получить к ним доступ с помощью оператора $ или [[“name”]].
  • 🇧🇷 Внесенные изменения: Переназначение обновляет элемент, а присвоение значения NULL удаляет его из списка.
  • 🔗 Сглаживание: Функция unlist() сводит вложенный список к одному атомарному вектору для последующего анализа.

Создание списка в языке программирования R и выбор элементов.

Что такое список R?

Р-список — это объект в программировании на R, который включает в себя матрицы, векторы, фреймы данных или списки. R List также используется для хранения коллекции объектов и использования их, когда они нам нужны. Мы можем представить список R как сумку, в которую можно положить множество разных предметов. Когда нам нужно использовать предмет, мы можем открыть сумку и использовать его.

В отличие от вектора, именно это делает «мешок» полезным. Вектор заставляет каждый элемент относиться к одному типу, поэтому, поместив слово рядом с числом, число превращается в текст. Список не подчиняется такому правилу, поэтому он может содержать пятиэлементный вектор, состоящий из двух строк. матрица и расположенный рядом фрейм данных из 714 строк, без каких-либо изменений в них.

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

Для создания списков в языке программирования R можно использовать функцию `list()`:

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

Каждый аргумент может быть представлен в чистом виде или в форме tag = значениеАргумент без метки становится позиционным элементом, достижимым только по его номеру, в то время как аргумент с меткой также получает имя. Базовая справочная информация R для список() В документации указаны обе формы, и отмечается, что unlist() является приблизительной обратной функцией к as.list().

Как создать список в R

Ниже приведен пошаговый процесс создания списка в R:

В приведенном ниже примере мы создадим три разных объекта: вектор, матрицу и объект. Фрейм данных используя функцию списка в 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] Подсписок, содержащий этот единственный элемент. список Необходимо сохранить обертку списка.
my_list[c(1, 3)] Подсписок выбранных элементов список Вам необходимо несколько элементов одновременно.
my_list[-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() должна возвращать один атомарный вектор, поэтому она преобразует каждое значение в наиболее общий из присутствующих типов, следуя порядку: логическое число, целое число, число с плавающей запятой, символ. Вложенный список, в котором числа смешаны с текстом, поэтому возвращается полностью в виде текста. Имена результата формируются путем объединения внешних и внутренних тегов, поэтому элемент поступает как 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

Следующий за read.csv() фрагмент [1:5] выбирает первые пять столбцов, а не первые пять строк, поскольку фрейм данных сам по себе является списком столбцов. Индексация списка в один квадратный скобочный указатель возвращает меньший список, и в данном случае этот меньший список по-прежнему является фреймом данных.

Мы можем проверить структуру фрейма данных с помощью 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 и к столбцам фрейма данных.

Часто задаваемые вопросы (FAQ)

Вектор заставляет каждый элемент иметь один и тот же тип, поэтому смешивание текста и чисел приводит к тому, что все элементы преобразуются в символьный формат. Список хранит каждый элемент точно в том виде, в котором он был предоставлен, включая векторы, матрицы и функции разной длины. Используйте функцию 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)` сначала помещает их в стек. дплир В экосистеме функция as_tibble() доступна в тех случаях, когда типы столбцов должны оставаться неизменными.

В списках отсутствует встроенная сортировка, поэтому, например,tracta compare key first: my_list[order(sapply(my_list, length))] переупорядочивает элементы по их размеру. Для прямоугольных данных преобразуйте их в фрейм и отсортировать фрейм данных Вместо этого используйте order().

Искусственный интеллект-помощники считывают вывод функции str() и объясняют, почему индекс вернул NULL или подсписок вместо значения. Они также предлагают правильную форму скобок, разрабатывают сценарии конвейеров lapply() и помечают скрытое приведение типов до того, как оно исказит результат.

Да. Второй пилот GitHub работает в RStudio Начиная с версии 2023.09.0 и более поздних, это делается через меню «Инструменты», «Глобальные параметры», а затем через настройку «Помощник кода». Он выполняет вызовы list(), names() и unlist() из комментария, хотя каждое предложение по-прежнему требует проверки.

Подведем итог этой публикации следующим образом: