Повторно изменяйте переменную, используя 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))