# Creating a Counter Function with DPLYR

I have the following dataset:

``````my_data = structure(list(id = c("A", "A", "A", "A", "A", "B", "B", "B",
"B"), result = c("AAA", "BBB", "CCC", "AAA", "CCC", "DDD", "BBB",
"BBB", "DDD")), class = "data.frame", row.names = c(NA, -9L))
``````

For each unique ID, am interested in learning about how to write a general function that updates a "counter variable" under certain conditions.

For example - for each unique ID:

• if result = AAA then counter restarts to 0
• if result = BBB then counter = counter + 1
• if result = CCC then counter = counter + 2
• if result = DDD then counter = counter - 1.

Here is my attempt to do this:

``````library(dplyr)

my_data %>%
group_by(id) %>%
mutate(counter = ifelse(result == "AAA", 0,
ifelse(result == "BBB", 1,
ifelse(result == "CCC", 2,
ifelse(result == "DDD", -1,
ifelse(result == 1, cumsum(result), 0))))))
``````

However, I don't think the results are correct - when I look at the results:

``````# A tibble: 9 x 3
# Groups:   id 
id    result counter
<chr> <chr>    <dbl>
1 A     AAA          0
2 A     BBB          1
3 A     CCC          2
4 A     AAA          0
5 A     CCC          2
6 B     DDD         -1
7 B     BBB          1
8 B     BBB          1
9 B     DDD         -1
``````

In the third row, the value of the counter should be 3 : 0 (result from row1) + 1 (result from row2) + 2 (result from row3).

I am trying different ways to debug this function to match my requirements, but so far nothing is working.

Can someone please show me how to correct this?

Thanks!

Note: I think the expected output should look something like this:

``````  id result counter
1  A    AAA       0
2  A    BBB       1
3  A    CCC       3
4  A    AAA       0
5  A    CCC       2
6  B    DDD      -1
7  B    BBB       0
8  B    BBB       1
9  B    DDD       0
``````

this seems to do it

``````
group_by(my_data, id) |>
mutate(
instance = case_when(
result == "BBB" ~ 1,
result == "CCC" ~ 2,
result == "DDD" ~ -1,
TRUE ~ 0
),
plaincounter = cumsum(instance),
resetcounter = cumsum(ifelse(result == "AAA", plaincounter, 0)),
counter = plaincounter - resetcounter
)``````
2 Likes

@ nirgrahamuk: Thank you for your answer! Do you know why result="AAA" needs to be specified?

Im afraid i dont undrdtand the question, can you rephrase ?

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.