biostatguy12
biostatguy12

Reputation: 659

Add a count column and count twice if a certain condition is met

I am wondering if there is a way to make a conditional column-count by a group, adding 1 to a row_number or rowid if a certain value is met (in this case 0). For example:

df<-data.frame(group=c(1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3,3,3,3), 
               condition=c(1,0,1,1,1,0,0,1,1,0,1,1,0, 1),
               want=c(1, 3, 4,5,1,3,5,6,7,2,3,4,6,7))
   group condition want
1      1         1    1
2      1         0    3
3      1         1    4
4      1         1    5
5      2         1    1
6      2         0    3
7      2         0    5
8      2         1    6
9      2         1    7
10     3         0    2
11     3         1    3
12     3         1    4
13     3         0    6
14     3         1    7

I think this might involve making a row_number per group and then making a customized row_number but I am open to suggestions. It is kind of a work-around method to "break up" my data when a 0 appears.

Upvotes: 2

Views: 142

Answers (2)

M--
M--

Reputation: 28850

Using dplyr, for each group of data (group-by(group)) we can add a column which has a counter from 1 to the length of each group (i.e. n()). By adding a cumulative sum of condition == 0, that counter will jump one more, whenever your desired condition is met.

library(dplyr)

df1 %>% 
  group_by(group) %>% 
  mutate(desired = (1:n()) + cumsum(condition == 0))

Output:

#> # A tibble: 14 x 3
#> # Groups:   group [3]
#>    group condition desired
#>    <dbl>     <dbl>   <int>
#>  1     1         1       1
#>  2     1         0       3
#>  3     1         1       4
#>  4     1         1       5
#>  5     2         1       1
#>  6     2         0       3
#>  7     2         0       5
#>  8     2         1       6
#>  9     2         1       7
#> 10     3         0       2
#> 11     3         1       3
#> 12     3         1       4
#> 13     3         0       6
#> 14     3         1       7

Data:

df1 <- data.frame(group=c(1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3,3,3,3), 
                  condition=c(1,0,1,1,1,0,0,1,1,0,1,1,0, 1))

Upvotes: 2

lroha
lroha

Reputation: 34441

You can do:

transform(df, want =  ave(condition, group, FUN = function(x) cumsum(x + (x == 0) * 2 )))

   group condition want
1      1         1    1
2      1         0    3
3      1         1    4
4      1         1    5
5      2         1    1
6      2         0    3
7      2         0    5
8      2         1    6
9      2         1    7
10     3         0    2
11     3         1    3
12     3         1    4
13     3         0    6
14     3         1    7

Upvotes: 2

Related Questions