Используйте цикл for для функции mutate с операцией.

Вопрос или проблема

Я пытался использовать цикл for, чтобы создать новые столбцы в фрейме данных, с которым я работаю, чтобы разработать новые переменные для анализа, и у меня возникает много проблем с этим.

У меня есть несколько переменных, которые относятся к акценту партий на различные политические вопросы, и я хотел создать переменные для каждого вопроса, принимая во внимание долю голосов, полученных партией (чтобы определить приближенную оценку того, сколько голосов связано с акцентом на вопрос i партией x).

Таким образом, новые столбцы будут применять следующую операцию: i_emphasis * pervote.

Код, который я написал, заимствован из другого ответа, который я посмотрел в Stack, так как мои первые попытки прошли довольно плохо, но я все равно не понимаю, что происходит. Вот код на данный момент:

vars <- c(y2016_ESP$per101:y2016_ESP$per706)

y2016_ESP %>% 
  for (i_var in vars){
      i_emphasis <- paste0("supp_i_",i_var)

      mod_y2016_ESP <- y2016_ESP %>%
        mutate(!!sym(i_emphasis) := i_var*pervote)
  }

i_var — это вектор, содержащий все столбцы “акцента на вопросы”, по которым он должен итерироваться, и, похоже, именно он вызывает проблемы. Я не понимаю, почему, так как c() должен взять каждый отдельный столбец и включить его в вектор (по крайней мере, я думаю, что он должен это делать).

Примечание: Для текущего кода я просто применяю его к сокращенному фрейму данных, так как хотел протестировать его и сначала описательно изучить этот маленький df, а затем применить его более широко к большему фрейму данных. Я видел, что некоторые другие люди используют функции apply() или lapply() для выполнения чего-то подобного, но я больше привык к циклам for, характерным для языков программирования.

Я думаю, что следующее соответствует тому, что вы хотите сделать.

library(dplyr)
y2016_ESP <- data.frame(
  per101 = 1:5,
  per501 = rnorm(5),
  per706 = runif(5)
  )

pervote <- .5

# mutate создает новые столбцы
y2016_ESP |>
  dplyr::mutate(
    dplyr::across(per101:per706, # аккуратно выбрать все столбцы между `per101` и `per706`
                  ~ .x * pervote, # анонимная функция в стиле dplyr
                  .names = "supp_i_{.col}") # именование новых столбцов в стиле glue
    )

Я думаю, что ваше замешательство связано с смешиванием концепций базового R и tidy-select в dplyr.

vars <- c(y2016_ESP$per101:y2016_ESP$per706) на самом деле не имеет смысла в базовом R, но этот стиль является одним из способов выбора столбцов с использованием dplyr и across.

glue в комментарии выше относится к пакету glue в R. Он часто работает аналогично строкам f в Python.

Вы обычно хотите выбирать между стилем базового R и стилем dplyr и избегать слишком большого смешивания концепций. (Конечно, это не всегда так.)

Я рекомендую книгу R для науки о данных, если вы собираетесь много работать с data.frames.

Если вы действительно хотите итерироваться по именам переменных, вы можете использовать базовый R вместо dplyr.

for (var in list_var) {
df[[var]] # сделайте свое дело
}

Ответ или решение

Чтобы создать новые столбцы в датафрейме в R с использованием цикла for и функции mutate из библиотеки dplyr, важно правильно структурировать код и учитывать некоторые тонкости, касающиеся выбора столбцов и работы с дублирующимися переменными. В данной ситуации мы хотим создать новые переменные, умножая существующие переменные эмфазы партий на общий процент голосов, который они получили.

Подход к решению задачи

  1. Создание векторов переменных: Важно убедиться, что вы правильно выбираете столбцы для итерации. Вместо того чтобы использовать c(y2016_ESP$per101:y2016_ESP$per706), рекомендуется использовать функции dplyr для более гибкого выбора столбцов.

  2. Использование mutate и for loop: Хотя dplyr имеет собственные функции для обработки данных, такие как mutate и across, возможно, что для большей визуализации вы хотите использовать циклы.

Реализация

Ниже приведен пример кода, который показывает, как правильно использовать цикл for вместе с mutate. Для начала создадим пример датафрейма и переменной для процента голосов:

library(dplyr)

# Пример датафрейма
y2016_ESP <- data.frame(
  per101 = 1:5,
  per501 = rnorm(5),
  per706 = runif(5)
)

# Процент голосов
pervote <- 0.5

# Список переменных к итерации
vars <- colnames(y2016_ESP)  # получаем названия всех столбцов

# Итерация по переменным
for (i_var in vars){
  # Создаем новое имя для переменной
  new_col_name <- paste0("supp_i_", i_var)

  # Обновляем датафрейм, добавляя новый столбец
  y2016_ESP <- y2016_ESP %>%
    mutate(!!sym(new_col_name) := .data[[i_var]] * pervote)
}

Пояснение к коду

  1. Создание датафрейма: Мы создали датафрейм y2016_ESP с некоторыми тестовыми данными.

  2. Процент голосов: У нас есть переменная pervote, которая хранит процент голосов, с помощью которого мы будем умножать значения эмфазы.

  3. Цикл for: Мы проходим по именам столбцов в vars, создаём новое имя для каждого столбца с помощью функции paste0, и с помощью функции mutate добавляем новый столбец в датафрейм.

  4. Использование !!sym: Мы используем !!sym() для преобразования строкового имени переменной в символ, который dplyr может распознать и использовать.

Заключение

Этот способ позволяет делать более сложные операции над датафреймом с использованием стандартных средств R. Обратите внимание на использование mutate для добавления новых переменных и использование двойного восклицательного знака (!!), который сообщает dplyr, что вы собираетесь передать символ в функцию. Для более эффективной работы с большим объемом данных вы можете использовать функции dplyr, такие как across, однако использование циклов может сделать ваш код более читаемым для тех, кто не знаком с функциональным программированием.

Рекомендации

  • Ознакомьтесь с литературой по R, например, "R for Data Science" by Hadley Wickham. Это поможет вам улучшить свои навыки в работе с данными.
  • Если вам необходимы более сложные операции, рассмотрите возможность использования функций lapply или sapply, так как они могут упростить операции по сравнению с ручными циклами.
Оцените материал
Добавить комментарий

Капча загружается...