Я хочу использовать dplyr::mutate()
для создания нескольких новых столбцов в кадре данных. Имена столбцов и их содержимое должны генерироваться динамически.
Пример данных из радужки:
library(dplyr)
iris <- tbl_df(iris)
Я создал функцию для изменения моих новых столбцов из Petal.Width
переменной:
multipetal <- function(df, n) {
varname <- paste("petal", n , sep=".")
df <- mutate(df, varname = Petal.Width * n) ## problem arises here
df
}
Теперь я создаю цикл для построения моих столбцов:
for(i in 2:5) {
iris <- multipetal(df=iris, n=i)
}
Однако, так как mutate думает, что varname является буквальным именем переменной, цикл создает только одну новую переменную (называемую varname) вместо четырех (называемых petal.2 - petal.5).
Как я могу mutate()
использовать свое динамическое имя в качестве имени переменной?
dplyr
есть целая виньетка о нестандартной оценкеmutate_
, и из других функций не совсем понятно, как ее использовать.Ответы:
Поскольку вы динамически строите имя переменной как символьное значение, имеет смысл выполнять присваивание с использованием стандартной индексации data.frame, которая допускает символьные значения для имен столбцов. Например:
mutate
Функция делает его очень легко назвать новые столбцы через именованные параметры. Но это предполагает, что вы знаете имя при вводе команды. Если вы хотите динамически указать имя столбца, вам также необходимо создать именованный аргумент.версия dplyr> = 0.7
Последняя версия
dplyr
(0.7) делает это с помощью:=
динамического присвоения имен параметров. Вы можете написать свою функцию как:Для получения дополнительной информации см. Документацию доступной формы
vignette("programming", "dplyr")
.dplyr (> = 0,3 и <0,7)
Чуть более ранняя версия
dplyr
(> = 0,3 <0,7) поощряла использование альтернатив «стандартной оценки» для многих функций. См. Нестандартную оценочную виньетку для получения дополнительной информации (vignette("nse")
).Итак, здесь ответ - использовать,
mutate_()
а неmutate()
делать:dplyr <0,3
Обратите внимание, что это также возможно в более старых версиях,
dplyr
которые существовали, когда вопрос был задан изначально. Это требует осторожного использованияquote
иsetName
:источник
do.call()
вероятно, не делает то, что вы думаете, что делает: rpubs.com/hadley/do-call2 . Смотрите также виньетка nse в версии dplyr для разработчиков.do.call
выше, чтобы использоватьdo.call("mutate")
и цитироватьdf
в списке. Это то, что вы предлагали? И когдаlazyeval
версияdplyr
будет выпущена, тогдаmutate_(df, .dots= setNames(list(~Petal.Width * n), varname))
будет лучшим решением?mutate(df, !!newVar := (!!var1 + !!var2) / 2)
не работает :(В новом выпуске
dplyr
(0.6.0
ожидается в апреле 2017 г.) мы также можем выполнить assignment (:=
) и передать переменные в качестве имен столбцов с помощью unquoting (!!
), чтобы не оценивать егоПроверка вывода на основе @ MrFlick,
multipetal
примененного к 'iris1'источник
После долгих проб и ошибок я обнаружил, что шаблон
UQ(rlang::sym("some string here")))
действительно полезен для работы со строками и глаголами dplyr. Кажется, это работает во многих удивительных ситуациях.Вот пример с
mutate
. Мы хотим создать функцию, которая складывает вместе два столбца, где вы передаете функции имена обоих столбцов в виде строк. Для этого мы можем использовать этот шаблон вместе с оператором присваивания:=
.Шаблон работает и с другими
dplyr
функциями. Вотfilter
:Или
arrange
:Для
select
вас не нужно использовать шаблон. Вместо этого вы можете использовать!!
:источник
myCol
на URL (например) и копирую старый столбецmyColInitialValue
в конце информационного кадраdf
с новым именем. Ноwhich(colnames(df)=='myCol')
отправить обратно колmyColInitialValue
. Я еще не написал проблему, потому что я не нашел представительство. Моя цель дляescape
параметраDT::datatable()
. Я используюescape=FALSE
в ожидании этого. С константами это тоже не работает, но пакет DT, похоже, тоже получает столбец bad #. :)escape
наDT::datatable
varname = sym("Petal.Width"); ggplot(iris, aes(x=!!varname)) + geom_histogram()
Вот еще одна версия, и, возможно, она немного проще.
источник
У
rlang 0.4.0
нас есть кудрявые операторы ({{}}
), что делает это очень просто.Мы также можем передавать имена переменных в кавычках / без кавычек для назначения в качестве имен столбцов.
Это работает так же с
источник
Я также добавляю ответ, который немного увеличивает это, потому что я пришел к этой записи при поиске ответа, и это было почти то, что мне было нужно, но мне нужно было немного больше, что я получил через ответ @MrFlik и Р лазевал виньетками.
Я хотел создать функцию, которая могла бы принимать фрейм данных и вектор имен столбцов (в виде строк), которые я хочу преобразовать из строки в объект Date. Я не мог понять, как заставить
as.Date()
аргумент, который является строкой, преобразовать его в столбец, поэтому я сделал это, как показано ниже.Ниже описано, как я это сделал с помощью SE mutate (
mutate_()
) и.dots
аргумента. Критика, которая делает это лучше, приветствуется.источник
В то время как мне нравится использовать dplyr для интерактивного использования, я считаю, что делать это с помощью dplyr чрезвычайно сложно, потому что вы должны пройти через обходы, чтобы использовать обходные пути lazyeval :: interp (), setNames и т. Д.
Вот более простая версия с использованием базы R, в которой, по крайней мере, мне кажется более интуитивно понятным поместить цикл в функцию, и которая расширяет решение @ MrFlicks.
источник
dplyr
много пользуюсь в неинтерактивных настройках, использование его с вводом переменных в функцию использует очень неуклюжий синтаксис.Вам может понравиться пакет,
friendlyeval
который представляет упрощенный tivy eval API и документацию для новых / случайныхdplyr
пользователей.Вы создаете строки, которые хотите
mutate
трактовать как имена столбцов. Таким образом, используяfriendlyeval
вы можете написать:Который под капотом вызывает
rlang
функции, которые проверяютсяvarname
как имя столбца.friendlyeval
код может быть преобразован в эквивалентный простой код в любое время с помощью надстройки RStudio.источник
Другая альтернатива: использовать
{}
внутри кавычек, чтобы легко создавать динамические имена. Это похоже на другие решения, но не совсем то же самое, и мне легче.Я думаю, что это происходит,
dplyr 1.0.0
но не уверен (у меня также есть,rlang 4.7.0
если это имеет значение).источник