Home > Software design >  Keeping values for first level of month in a data frame while set rest of the values to zero in R
Keeping values for first level of month in a data frame while set rest of the values to zero in R

Time:09-29

I have the following data set;

df <- matrix(data = c("G1", "March", 98.97291, 
                      "G1", "April", 95.99673,
                      "G2", "January", 97.46496,
                      "G2", "February", 100.56501,
                      "G2", "March", 99.43287, 
                      "G2", "April", 103.00277,
                      "G2", "November", 98.11647, 
                      "G2", "December", 101.56892),
             nrow = 8, ncol = 3, byrow = T
)

df <- as.data.frame(df)
colnames(df) <- c("group", "month", "values")
df$values <- as.numeric(df$values)

The output of the df object is given below:

   group   month  values
1    G1    March  98.97291
2    G1    April  95.99673
3    G2  January  97.46496
4    G2 February 100.56501
5    G2    March  99.43287
6    G2    April 103.00277
7    G2 November  98.11647
8    G2 December 101.56892

I wants to keep values for each group G1 and G2 only for first level of the month. For example in G1 for the month March and in G2 for the month January the values should remain in the data frame while I want to set rest of the values to zero.

I would be thankful for your help in this regard.

CodePudding user response:

With ifelse row_number:

library(dplyr)
df %>% 
  group_by(group) %>% 
  mutate(values = ifelse(row_number() == 1, values, 0))

output

  group month    values
  <chr> <chr>     <dbl>
1 G1    March      99.0
2 G1    April       0  
3 G2    January    97.5
4 G2    February    0  
5 G2    March       0  
6 G2    April       0  
7 G2    November    0  
8 G2    December    0  

Also works with replace:

df %>% 
  group_by(group) %>% 
  mutate(values = replace(values, row_number() != 1, 0))

CodePudding user response:

The solutions from Maël already work fine, here's just another way using case_when:

library(dplyr)
df |> 
  group_by(group) |> 
  mutate(values = case_when(
    month == first(month) ~ values,
    TRUE ~ 0
  ))
  • Related