9

I try to mutate new column to data.frame. When V column order changes from decreasing to increasing order, I use diff function inside of mutate to categorize them in new column H.

V <- c(seq(30,-10,-10),seq(-10,30,10))
gr = rep(seq(1,3),each=10)
df <- data.frame(V,gr)

library(dplyr)    
diff_df <- df%>%
  group_by(gr)%>%
  mutate(H=ifelse(diff(V)<0,"back","forward"))

However getting error

Error: incompatible size (9), expecting 10 (the group size) or 1

But when I do

diff(df$V)

[1] -10 -10 -10 -10 0 10 10 10 10 0 -10 -10 -10 -10 0 10 10 10 10 0 -10 -10 -10 -10 0 10 10 10 10

seems to be working logically. Why I'm getting error when I do inside of dplyr?

Alexander
  • 4,527
  • 5
  • 51
  • 98

1 Answers1

10

We need to concatenate with one more value to make the length equal as diff returns with a length one less than the length of the group. i.e.

length(df$V)
#[1] 30
length(diff(df$V))
#[1] 29

So, we concatenate with a dummy number at the beginning to make the length equal.

 df %>%
   group_by(gr) %>%
   mutate(H=ifelse(c(0,diff(V))<0,"back","forward"))

If we need the first value to be 'back', change the condition to <=0

akrun
  • 874,273
  • 37
  • 540
  • 662
  • 8
    A more `dplyr`-y alternative would be to replace `diff` with `V - lag(V)`. (or perhaps `V - lag(V, 1, 0)`) – Axeman Feb 03 '16 at 08:29
  • 1
    How would you do this for mutate_each? – jhilliar Apr 13 '17 at 02:48
  • 3
    @jhilliar The `mutate_each` will soon becomes replaced. `df %>% group_by(gr) %>% mutate_all(funs(ifelse(c(0, diff(.)) < 0, "back", "forward")))` – akrun Apr 13 '17 at 02:50