При работе с ним plyr
я часто находил полезным использовать adply
скалярные функции, которые мне приходилось применять к каждой строке.
например
data(iris)
library(plyr)
head(
adply(iris, 1, transform , Max.Len= max(Sepal.Length,Petal.Length))
)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Max.Len
1 5.1 3.5 1.4 0.2 setosa 5.1
2 4.9 3.0 1.4 0.2 setosa 4.9
3 4.7 3.2 1.3 0.2 setosa 4.7
4 4.6 3.1 1.5 0.2 setosa 4.6
5 5.0 3.6 1.4 0.2 setosa 5.0
6 5.4 3.9 1.7 0.4 setosa 5.4
Теперь я использую dplyr
больше, мне интересно, есть ли аккуратный / естественный способ сделать это? Поскольку это НЕ то, что я хочу:
library(dplyr)
head(
mutate(iris, Max.Len= max(Sepal.Length,Petal.Length))
)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Max.Len
1 5.1 3.5 1.4 0.2 setosa 7.9
2 4.9 3.0 1.4 0.2 setosa 7.9
3 4.7 3.2 1.3 0.2 setosa 7.9
4 4.6 3.1 1.5 0.2 setosa 7.9
5 5.0 3.6 1.4 0.2 setosa 7.9
6 5.4 3.9 1.7 0.4 setosa 7.9
mdply
in dplyr, и Хэдли предположил, что они могут варить что-то на основеdo
. Думаю, здесь тоже сработает.rowwise()
что будет группироваться по каждой отдельной строкеadply
если бы вы не использовали группировку? поскольку его тесно интегрированная функция называетсяgroup_by
НЕsplit_by
Ответы:
Поскольку dplyr 0.2 (я думаю)
rowwise()
реализован, поэтому ответ на эту проблему таков:Non
rowwise
альтернативаСпустя пять лет (!) Этот ответ все еще пользуется большой популярностью. Поскольку это было дано,
rowwise
все чаще не рекомендуется, хотя многие люди, кажется, находят его интуитивно понятным. Сделайте себе одолжение и ознакомьтесь с рабочими процессами Дженни Брайан, ориентированными на строки в R, с материалом tidyverse, чтобы лучше разобраться в этой теме.Самый простой способ, который я нашел, основан на одном из примеров Хэдли
pmap
:Используя этот подход, вы можете передать произвольное количество аргументов функции (
.f
) внутриpmap
.pmap
- хороший концептуальный подход, поскольку он отражает тот факт, что при выполнении строковых операций вы фактически работаете с кортежами из списка векторов (столбцы в фрейме данных).источник
plyr
иdplyr
пакеты, вы почти наверняка с помощью неправильно ,mutate
если вы явно не предоставите сферыdplyr::mutate
.Идиоматический подход заключается в создании соответствующим образом векторизованной функции.
R
provide,pmax
который подходит здесь, однако он также предоставляетVectorize
в качестве оболочки дляmapply
создания векторизованной произвольной версии произвольной функции.Обратите внимание, что реализация векторизации на C / C ++ будет быстрее, но нет
magicPony
пакета, который напишет функцию за вас.источник
dplyr
способ ... так как было бы проще без dplyr, например,with(df, Coalesce(a,b))
возможно, это ответ вроде - не использоватьdplyr
для этого?magicPony
пакета нет. Слишком плохоВам нужно сгруппировать по строкам:
Это то, что
1
сделали вadply
.источник
dplyr
эксперт. Надеюсь, кто-то другой предложит что-нибудь получше. Обратите внимание, я немного очистил его с помощью1:n()
.group_by(1:n())
поведение. Если утром ни у кого не будет других идей, я помечу вашу;)n
: «Эта функция реализована специально для каждого источника данных и может использоваться только из summarize.», Хотя, похоже, это работает.Обновление 2017-08-03
Написав это, Хэдли снова кое-что изменил. Функции, которые раньше находились в purrr, теперь находятся в новом смешанном пакете под названием purrrlyr , описанном как:
Итак, вам нужно будет установить + загрузить этот пакет, чтобы приведенный ниже код работал.
Исходный пост
Хэдли часто меняет свое мнение о том, что нам следует использовать, но я думаю, что мы должны переключиться на функции в purrr, чтобы получить функциональность по строкам. По крайней мере, они предлагают тот же функционал и почти такой же интерфейс, что и
adply
у plyr .Есть две связанные функции
by_row
иinvoke_rows
. Насколько я понимаю, вы используете,by_row
когда хотите перебрать строки и добавить результаты в data.frame.invoke_rows
используется, когда вы перебираете строки в data.frame и передаете каждый столбец в качестве аргумента функции. Мы будем использовать только первый.Примеры
Это позволяет нам видеть внутреннее устройство (чтобы мы могли видеть, что мы делаем), что аналогично тому, как мы делаем это с
adply
.По умолчанию
by_row
добавляет столбец списка на основе вывода:дает:
если вместо этого мы вернем a
data.frame
, мы получим список сdata.frame
s:дает:
То, как мы добавляем вывод функции, контролируется параметром
.collate
param. Есть три варианта: список, строки, столбцы. Когда наш вывод имеет длину 1, не имеет значения, используем ли мы строки или столбцы.оба производят:
Если мы выводим data.frame с 1 строкой, неважно, что мы используем:
оба дают:
за исключением того, что во втором столбце
.row
вызывается, а в первом нет.Наконец, если наш вывод длиннее 1 либо как,
vector
либо какdata.frame
со строками, то имеет значение, используем ли мы строки или столбцы для.collate
:производит соответственно:
Итак, итоги. Если вам нужна
adply(.margins = 1, ...)
функциональность, вы можете использоватьby_row
.источник
by_row
устарело, вызывая его, чтобы "использовать комбинацию: tidyr :: nest (); dplyr :: mutate (); purrr :: map ()" github.com/hadley/purrrlyr/blob/…Расширяя ответ BrodieG,
Если функция возвращает более одной строки, вместо
mutate()
,do()
необходимо использовать. Затем, чтобы снова соединить, используйтеrbind_all()
изdplyr
упаковки.В
dplyr
версииdplyr_0.1.2
использование1:n()
вgroup_by()
предложении у меня не работает. Надеюсь, Хэдли скоро реализуетrowwise()
.Тестирование производительности,
он дает следующие результаты:
Это показывает, что новая
purrr
версия самая быстраяисточник
Что-то вроде этого?
источник
dplyr
решение для какой-либо скалярной функции.wacky.function <- function(col.1, col.2){...}
, а затемiris.wacky <- wacky.function(iris$Sepal.Length, iris$Petal.Length)
.dplyr
илиplyr
или говорите,data.table
вы должны попытаться использовать их идиомы, чтобы ваш код не стал трудным для совместного использования сочетания стилей. Отсюда вопрос.plyr
документации: «plyr - это набор инструментов, который решает общий набор проблем: вам нужно разбить большую проблему на управляемые части, обработать каждую часть, а затем собрать все части вместе». Это похоже на совсем другую проблему, для которой элементарные операции с столбцами являются лучшим инструментом. Это также может объяснить, почему для этого нет "естественной" командыplyr
/dplyr
.