lundi 17 août 2020

Is there a way to do a conditional and multiple row by row operation along a sorted and grouped tibble?

I have a grouped tibble where several parameters have to be calculated from others assuming a function that gets its values from a previous row. I have tried to find answers that involve lag, mutate, case_when, and aggregate but had no luck implementing these in the following toy dataset:

library(tidyverse)

set.seed(42)

df <- tibble(
  gr = c(1,1,1,2,2,2),
  t = rep((seq(1:3)),2),
  v1 = c(1,NA,NA,1.6,NA,NA),
  v2 = rnorm(6),
  v3 = c(-0.2,0.3,-0.6,-0.2,1,0.2)
  ) 

# These operations 
(df <- df %>% group_by(gr) %>%  
  arrange(t, .by_group = TRUE) %>% 
  mutate(R1=abs(v1-5*v2)) %>% 
  mutate(R2=(R1^(1/2))) %>% 
  mutate(RI3=R1/R2)) 

# would finalize the tibble:
# A tibble: 6 x 8
# Groups:   gr [2]
     gr     t    v1     v2    v3    R1    R2   RI3
  <dbl> <int> <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl>
1     1     1   1    1.37   -0.2  5.85  2.42  2.42
2     1     2  NA   -0.565   0.3 NA    NA    NA   
3     1     3  NA    0.363  -0.6 NA    NA    NA   
4     2     1   1.6  0.633  -0.2  1.56  1.25  1.25
5     2     2  NA    0.404   1   NA    NA    NA   
6     2     3  NA   -0.106   0.2 NA    NA    NA   

Now, what I would need to do is to use df$RI3[i-1] as input for df$v1[i]

if ia.na(df$v1[i]) is TRUE and subsequently calculate:

mutate(R1=abs(v1-5*v2))  %>%  mutate(R2=(R1^(1/2))) %>% mutate(RI3=R1/R2)  

row-by-row in order to fill the gaps within the sorted and grouped dataset;

doing this one by one would look like this:

Rdf <-   df
Rdf$v1[2] <- df$RI3[1]
Rdf$v1[5] <- df$RI3[4]
Rdf <- Rdf %>%  mutate(R1=abs(v1-5*v2)) %>% 
  mutate(R2=(R1^(1/2))) %>% mutate(RI3=R1/R2) 
Rdf 
Rdf$v1[3] <- Rdf$RI3[2]
Rdf$v1[6] <- Rdf$RI3[5]
Rdf <- Rdf %>%  mutate(R1=abs(v1-5*v2)) %>% 
  mutate(R2=(R1^(1/2))) %>% mutate(RI3=R1/R2) 

and would result in:

# A tibble: 6 x 8
# Groups:   gr [2]
     gr     t    v1      v2    v3     R1    R2   RI3
  <dbl> <int> <dbl>   <dbl> <dbl>  <dbl> <dbl> <dbl>
1     1     1  1    -0.292   -0.2 2.46   1.57  1.57 
2     1     2  1.57  0.722    0.3 2.04   1.43  1.43 
3     1     3  1.43  0.281   -0.6 0.0246 0.157 0.157
4     2     1  1.6  -0.665   -0.2 4.92   2.22  2.22 
5     2     2  2.22 -0.0129   1   2.28   1.51  1.51 
6     2     3  1.51  0.146    0.2 0.783  0.885 0.885

Any help with this is very welcome!

Aucun commentaire:

Enregistrer un commentaire