Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate groupwise ratio of consecutive values in R

Tags:

r

I want to calculate the ratio between consecutive values within groups. It is easy for differences using diff:

mdata <- data.frame(group = c("A","A","A","B","B","C","C"), x = c(2,3,5,6,3,7,6))   
mdata$diff <- unlist(by(mdata$x, mdata$group, function(x){c(NA, diff(x))}))
mdata

  group x diff
1     A 2   NA
2     A 3    1
3     A 5    2
4     B 6   NA
5     B 3   -3
6     C 7   NA
7     C 6   -1

Is there an equivalent function to calculate ratios? Desired output would be:

  group x     ratio
1     A 2        NA
2     A 3 1.5000000
3     A 5 1.6666667
4     B 6        NA
5     B 3 0.5000000
6     C 7        NA
7     C 6 0.8571429
like image 803
Sophia Avatar asked Jan 28 '14 19:01

Sophia


2 Answers

Try dplyr:

install.packages(dplyr)
require(dplyr)
mdata <- data.frame(group = c("A","A","A","B","B","C","C"), x = c(2,3,5,6,3,7,6))   
mdata <- group_by(mdata, group)
mutate(mdata, ratio = x / lag(x))

# Source: local data frame [7 x 3]
# Groups: group

#   group x     ratio
# 1     A 2        NA
# 2     A 3 1.5000000
# 3     A 5 1.6666667
# 4     B 6        NA
# 5     B 3 0.5000000
# 6     C 7        NA
# 7     C 6 0.8571429

Your diff would simplify to:

mutate(mdata, diff = x - lag(x))

# Source: local data frame [7 x 3]
# Groups: group

#   group x diff
# 1     A 2   NA
# 2     A 3    1
# 3     A 5    2
# 4     B 6   NA
# 5     B 3   -3
# 6     C 7   NA
# 7     C 6   -1
like image 111
Vincent Avatar answered Sep 18 '22 22:09

Vincent


Same idea, using data.table:

library(data.table)
dt = as.data.table(mdata)

dt[, ratio := x / lag(x), by = group]
dt
#   group x     ratio
#1:     A 2        NA
#2:     A 3 1.5000000
#3:     A 5 1.6666667
#4:     B 6        NA
#5:     B 3 0.5000000
#6:     C 7        NA
#7:     C 6 0.8571429
like image 21
eddi Avatar answered Sep 17 '22 22:09

eddi