LDT
LDT

Reputation: 3088

Conditional replacing of a numeric value in dplyr

Dear all I have a data frame that looks like this

df <- data.frame(time=c(1,2,3,4,1,2,3,4,5), type=c("A","A","A","A","B","B","B","B","B"), count=c(10,0,0,1,8,0,1,0,1))
df

 time type count
1    1    A    10
2    2    A     0
3    3    A     0
4    4    A     1
5    1    B     8
6    2    B     0
7    3    B     1
8    4    B     0
9    5    B     1

I want to examine each group of types and if I see that one count is 0 then to replace the next count forward in time with 0. I do not count to be resurrected from the zero.

I want my data to looks like this

 time type count
1    1    A    10
2    2    A     0
3    3    A     0
4    4    A     0
5    1    B     8
6    2    B     0
7    3    B     0
8    4    B     0
9    5    B     0

Upvotes: 0

Views: 213

Answers (3)

Alan G&#243;mez
Alan G&#243;mez

Reputation: 378

A Base R way to do that:

n <- length(df$type)
df$count <- c(1,ifelse(df$type[1:(n-1)] == df$type[2:n],0,1))*df$count

OUTPUT:

df
  time type count
1    1    A    10
2    2    A     0
3    3    A     0
4    4    A     0
5    1    B     8
6    2    B     0
7    3    B     0
8    4    B     0
9    5    B     0

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 388972

You may use cummin function.

library(dplyr)
df %>% group_by(type) %>% mutate(count = cummin(count))

#   time type  count
#  <dbl> <chr> <dbl>
#1     1 A        10
#2     2 A         0
#3     3 A         0
#4     4 A         0
#5     1 B         8
#6     2 B         0
#7     3 B         0
#8     4 B         0
#9     5 B         0

Since cummin is a base R function you may also implement it in base R -

transform(df, count = ave(count, type, FUN = cummin))

Upvotes: 2

Yuriy Saraykin
Yuriy Saraykin

Reputation: 8880

If I understood correctly

library(tidyverse)
df <-
  data.frame(
    time = c(1, 2, 3, 4, 1, 2, 3, 4, 5),
    type = c("A", "A", "A", "A", "B", "B", "B", "B", "B"),
    count = c(10, 0, 0, 1, 8, 0, 1, 0, 1)
  )

df %>% 
  group_by(type) %>% 
  mutate(count = if_else(lag(count, default = first(count)) == 0, 0, count))
#> # A tibble: 9 x 3
#> # Groups:   type [2]
#>    time type  count
#>   <dbl> <chr> <dbl>
#> 1     1 A        10
#> 2     2 A         0
#> 3     3 A         0
#> 4     4 A         0
#> 5     1 B         8
#> 6     2 B         0
#> 7     3 B         0
#> 8     4 B         0
#> 9     5 B         0

Created on 2021-09-10 by the reprex package (v2.0.1)

Upvotes: 3

Related Questions