HCAI
HCAI

Reputation: 2263

Couple a function inside mutate dplyr r: Calculate second derivative

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

Answers (1)

akrun
akrun

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

Related Questions