Using ddply + mutate with a custom function?

I use ddplyquite often, but historically with summarize(sometimes mutate) and only basic functions such as mean(), var1 - var2etc. I have a dataset in which I am trying to apply a custom, more involved function and started trying to figure out how to do this with ddply. I have a successful solution, but I don’t understand why it works the same way as for more “normal” functions.

Similar

Here is an example dataset:

library(plyr)
df <- data.frame(id = rep(letters[1:3], each = 3),
                 value = 1:9)

Normally I would use ddplyas follows:

df_ply_1 <- ddply(df, .(id), mutate, mean = mean(value))

My visualization of this is that it ddplysplits dfdata into “mini” frames based on grouped combos id, and then I add a new column, calling mean()by the name of the column that exists in df. So, my attempt to implement a function has expanded this idea:

# actually, my logical extension of the above was to use:
# ddply(..., mean = function(value) { mean(value) })
df_ply_2 <- ddply(df, .(id), mutate,
                  mean = function(df) { mean(df$value) })

Error: attempt to replicate an object of type 'closure'

All help on user-defined functions does not apply mutate, but it seems inconsistent or at least annoying me, since the analogue of my implemented solution is:

df_mean <- function(df) {
    temp <- data.frame(mean = rep(mean(df$value), nrow(df)))
    temp
}

df_ply_3 <- df
df_ply_3$mean <- ddply(df, .(id), df_mean)$mean

On the line, it looks like I should do this:

df_ply_4 <- df
df_ply_4$mean <- ddply(df, .(id), function(x) {
    temp <- data.frame(mean = rep(mean(x$value), length(x$value)))
    temp})$mean

mutate ? , "" , ddply data.frame, , ?

, ""!


@Gregor

, , . , mutate summarize... , ddply , . , .

, , mutate/summarize data.frame, cbind df, .

, mutate, , . , , :

# I also caught that the code above doesn't do the right thing
# and recycles the single value returned by mean() vs. repeating it like
# I expected. Now that I know it taking a vector, I know I need to return
# a vector the same length as my mini df
custom_mean <- function(x) {
    rep(mean(x), length(x))
}

df_ply_5 <- ddply(df, .(id), mutate,
              mean = custom_mean(value))

!


@Gregor

. rep(mean(x), length(x)) - df_ply_3 ( , , , , , !):

df_mean <- function(x) {
    data.frame(mean = mean(x$value))
}

df_ply_3 <- df
df_ply_3$mean <- ddply(df, .(id), df_mean)$mean

df_ply_3
  id value mean
1  a     1    2
2  a     2    5
3  a     3    8
4  b     4    2
5  b     5    5
6  b     6    8
7  c     7    2
8  c     8    5
9  c     9    8

, , , , 3 id , 3 . , summarize ( id) . , :

df <- data.frame(id = c(rep(letters[1:3], each = 3), "d"),
                 value = 1:10)

df_ply_3 df_mean():

Error in `$<-.data.frame`(`*tmp*`, "mean", value = c(2, 5, 8, 10)) : 
  replacement has 4 rows, data has 10

, -df, df_mean, a df, mean , value ( ). , data.frame , id. , mutate "", - , ?

, df_ply_5; , rep() mean(x), !

+4
1

. ddply - .

ddply , .fun () .

mutate summarize - , ( ). ddply, , .

mutate(mtcars, mean.mpg = mean(mpg))
summarize(mtcars, mean.mpg = mean(mpg))

mutate summarize, , () , .

mutate summarize, , ddply, ddply, mutate summarize. , mutate summarize, , data.frame.

ddply(mtcars, "cyl", mutate, mean.mpg = mean(mpg))

, mutate. ddply(mtcars, "cyl", mutate, mean). , . ?mutate ... - " , ", - . (Is mean() " "? .)

, - . ! .

custom_function <- function(x) {mean(x + runif(length(x))}
ddply(mtcars, "cyl", mutate, jittered.mean.mpg = custom_function(mpg))
ddply(mtcars, "cyl", summarize, jittered.mean.mpg = custom_function(mpg))

, , , , mutate summarize, ; .

, ddply , "", . , , mutate summarize, . summarize -like data.frame , mutate -like data.frame cbind ed on

mean.mpg.mutate = function(df) {
    cbind.data.frame(df, mean.mpg = mean(df$mpg))
}

mean.mpg.summarize = function(df) {
    data.frame(mean.mpg = mean(df$mpg))
}

ddply(mtcars, "cyl", mean.mpg.mutate)
ddply(mtcars, "cyl", mean.mpg.summarize)

TL;DR

mutate ? , "" - , ddply , data.frame, , ?

! mutate summarize . - , , ddply, - .

- , 99% , ddply.

mutate/summaryize, .

mutate/summary, , , () . , , ( ). , . , mean; , mean(mpg).


dplyr?

, dplyr -, , , . dplyr , ddply mutate summarize group_by, mutate summarize. dplyr

library(dplyr)
group_by(mtcars, cyl) %>%
    mutate(mean.mpg = mean(mpg))

mutate ( summarize), , .

+11

All Articles