piravi
piravi

Reputation: 209

how to apply a function to each group

I have this function*,

x<- data.frame (
  'Ones'=c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0), 
  'Thats'=c(0,5,3,6,8,4,5,6,8,3,1,NA,4,5,6,7,4,3,4,5))


f<- function(df, n){
  df %>%
    collapse::flag(-n:n) %>%
    rowSums(na.rm = T) - 1
}

x %>%
  mutate(gap1 = f(., 1),
         gap2 = f(., 2), 
          gap3 = f(., 3),
          gap4 = f(., 4),
          gap5 = f(., 5)) %>%
  filter(Ones == 1)

It finds when the variable Ones is qual to 1 and sums, if gap1 = f(., 1), the values n-1, n and n+1 in Thats, with n being in the same row as 1, if gap2 = f(.,2) n-2 + n-1 + n + n+1 + n+2... And so on.

This is the output.

Ones Thats gap1 gap2 gap3 gap4 gap5
1    1     0    5    8   14   22   27
2    1     4   17   29   40   48   51
3    1     1    4   16   27   38   50

Now I want to use this function for each group of my sample. This is a Facsimile of my sample. The real sample has more conditions and more observation, but this is just to give you an idea.

dat<- data.frame (
  'sub'   = c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2),
  'trial' = c(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2),
  'Thumb'=  c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0), 
  'Index'=  c(0,5,3,6,8,4,5,6,8,3,1,3,4,5,6,7,4,3,4,5,4,5,3,23,2,1,4,6,3,2,3,2,4,6,3,2,4,3,2,1))

I need to apply the function to all groups of my sample.

For example, in this specific case I would 4 conditions:

sub1/trial1, sub2/trial1, sub1/trial2, sub2/trial2

I tried to write the function in this way:

f<- function(df, n){
  df %>% group_by(trial, sub) %>%
    collapse::flag(-n:n) %>%
    rowSums(na.rm = T) - 1
}

But it doesn't work.

Do you have any advice to give me?

Please consider that the sample above is only an example... I need a general function working also with more conditions and observations.

Thank you, Best regards

*credits: Kindly proposed by Donald Seinen on this site.

Upvotes: 2

Views: 74

Answers (1)

akrun
akrun

Reputation: 886938

We may need group_modify if we are using the first function f

library(dplyr)
dat %>% 
   group_by(trial, sub) %>% 
   group_modify(~ .x %>% 
       mutate(gap1 = f(.x, 1), gap2 = f(.x, 2), 
          gap3 = f(.x, 3), gap4 = f(.x, 4), gap5 = f(.x, 5))) %>%
    ungroup

-output

# A tibble: 40 × 9
   trial   sub Thumb Index  gap1  gap2  gap3  gap4  gap5
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1     1     1     1     0     5     8    14    22    27
 2     1     1     0     5     8    14    22    27    32
 3     1     1     0     3    13    22    27    32    38
 4     1     1     0     6    16    26    32    38    46
 5     1     1     0     8    18    26    37    46    49
 6     1     1     1     4    17    29    40    48    49
 7     1     1     0     5    15    31    40    43    48
 8     1     1     0     6    18    26    34    40    43
 9     1     1     0     8    16    21    26    34    40
10     1     1     0     3    10    16    21    26    34
# … with 30 more rows

which is the same result we get on the subset of data for the first combination

> dat %>%
    filter(sub == 1, trial == 1) %>% 
    select(-sub, -trial) %>% 
    mutate(gap1 = f(., 1),
          gap2 = f(., 2), 
           gap3 = f(., 3),
           gap4 = f(., 4),
           gap5 = f(., 5))
   Thumb Index gap1 gap2 gap3 gap4 gap5
1      1     0    5    8   14   22   27
2      0     5    8   14   22   27   32
3      0     3   13   22   27   32   38
4      0     6   16   26   32   38   46
5      0     8   18   26   37   46   49
6      1     4   17   29   40   48   49
7      0     5   15   31   40   43   48
8      0     6   18   26   34   40   43
9      0     8   16   21   26   34   40
10     0     3   10   16   21   26   34

Upvotes: 2

Related Questions