Reputation: 2263
I would like to calculate the following formula on all my data grouped_by(id)
$$\frac{y''}{((1+(y')^2)^{3/2}}$$
I'm getting stuck on passing a function through mutate because it gives me unequal column sizes.
Sample data is:
require(dplyr)
df<-data.frame(Time=seq(65),
SkinTemp=rnorm(65,37,0.5),
id=rep(1:10,c(5,4,10,6,7,8,9,8,4,4)))
First derivative (OK):
df <-df %>% group_by(id) %>% filter(n() > 1) %>%
mutate(first_d = SkinTemp - lag(SkinTemp))
df<-as.data.frame(df) #Back to data frame
Second derivative (stuck):
drv <- function(x, y) diff(y) / diff(x) #Defined this to pass to mutate
middle_pts <- function(x) x[-1] - diff(x) / 2
second_d <-df %>% group_by(id) %>%
mutate(second_d = drv(middle_pts(Time), drv(Time, SkinTemp)))
Upvotes: 1
Views: 764
Reputation: 887691
The diff
returns a vector of length one less than the original vector
. The function mutate
requires the column to return the same length. Therefore, we need to do some appending with NA
or value of choice
drv <- function(x, y) c(NA, (diff(y) /diff(x)))
middle_pts <- function(x) c(NA, (x[-1] - diff(x) /2))
Now, the OP's code should work
df %>%
group_by(id) %>%
mutate(second_d = drv(middle_pts(Time), drv(Time, SkinTemp)))
Upvotes: 2