Повторно изменяйте переменную, используя dplyr и purrr.

Я самоучка в R, и это мой первый вопрос Stackru. Я прошу прощения, если это очевидная проблема; пожалуйста, будь добр.

Краткая версия моего вопроса
Я написал пользовательскую функцию для расчета процентного изменения переменной в течение года. Я хотел бы использовать purrr"s map_at функция для применения моей пользовательской функции к вектору имен переменных. Моя пользовательская функция работает, когда применяется к одной переменной, но не работает, когда я ее чередую map_a

Моя пользовательская функция

calculate_delta <- function(df, col) {

  #generate variable name
  newcolname = paste("d", col, sep="")

  #get formula for first difference.
  calculate_diff <- lazyeval::interp(~(a + lag(a))/a, a = as.name(col))

  #pass formula to mutate, name new variable the columname generated above
  df %>% 
        mutate_(.dots = setNames(list(calculate_diff), newcolname)) }

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

calculate_delta(mtcars, "wt")

Попытка применить функцию к символьному вектору с помощью Purrr

Я думаю, что мне трудно понять, как map_at передает аргументы в функцию. Все примеры фрагментов, которые я могу найти в Интернете, используют map_at с такими функциями, как is.character, которые не требуют дополнительных аргументов. Вот мои попытки применения функции с помощью purrr,

vars <- c("wt", "mpg")
mtcars %>% map_at(vars, calculate_delta)

Это дает мне это сообщение об ошибке

Ошибка в вставке ("d", col, sep = ""): отсутствует аргумент "col", по умолчанию нет

Я предполагаю, что это потому, что map_at проходит vars как dfи не передавая аргумент для col, Чтобы обойти эту проблему, я попробовал следующее:

vars <- c("wt", "mpg") 
mtcars %>% map_at(vars, calculate_delta, df = .)

Это бросает мне эту ошибку:

Error: unrecognised index type

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

Другие потенциальные решения

1) версия этого с использованием sapply, скорее, чем purrr, Я пытался решить проблему таким образом, и у меня были похожие проблемы. И моя цель - найти способ сделать это с помощью мурлыкания, если это возможно. Основываясь на моем понимании purrrЭто похоже на типичный вариант использования.

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

Я явно думаю, что это неправильно. Пожалуйста помоги!

РЕДАКТИРОВАТЬ 1

Чтобы уточнить, мне любопытно, если есть метод многократного преобразования переменных, который выполняет две вещи.

1) Создает новые переменные в оригинале tbl_df без замены замените изменяемые столбцы (как в случае использования dplyr"s mutate_at).

2) Автоматически генерирует новые метки переменных.

3) Если возможно, выполняет то, что я описал, применяя одну функцию, используя map_at,

Может быть, это невозможно, но я чувствую, что должен быть элегантный способ выполнить то, что я описываю.

1 ответ

Решение

Попробуйте упростить процесс:

delta <- function(x) (x + dplyr::lag(x)) /x
cols <- c("wt", "mpg")

#This
library(dplyr)
mtcars %>% mutate_at(cols, delta)
#Or
library(purrr)
mtcars %>% map_at(cols, delta)

#If necessary, in a function
f <- function(df, cols) {
  df %>% mutate_at(cols, delta)
}

f(iris, c("Sepal.Width", "Petal.Length"))
f(mtcars, c("wt", "mpg"))

редактировать

Если вы хотите встраивать новые имена после, мы можем написать пользовательскую функцию готовности к конвейеру:

Rename <- function(object, old, new) {
  names(object)[names(object) %in% old] <- new
  object
}

mtcars %>% 
  mutate_at(cols, delta) %>% 
  Rename(cols, paste0("lagged",cols))

Если вы хотите переименовать результирующие отстающие переменные:

mtcars %>% mutate_at(cols, funs(lagged = delta))
Другие вопросы по тегам