rduplicatestidyversemutated

Repeat row and mutate multiple observations on conditional statement


I'm trying write a conditional statement that duplicates the row where df$food=1. Then changes the value "df$weight" of initial row to the value of df$prior_w and not the duplicate. Also i need to change the df$food value to 0 on the duplicate and prior_w to NA on the duplicate

df <- data.frame(date=("2022-01-01","2022-01-02","2022-01-03","2022-01-04","2022-01-05"),
food=(0,0,0,1,0),
prior_w=(NA,NA,NA,2,NA),
weight=(5,4,3,6,4))

Id like to have a data frame like this

df_2 <- data.frame(date=("2022-01-01","2022-01-02","2022-01-03","2022-01-04","2022-01-04","2022-01-05"),
food=(0,0,0,1,0,0),
prior_w=(NA,NA,NA,NA,2,NA),
weight=(5,4,3,2,6,4))

Im will translate what i need in words (Not actual code, sorry im struggling). I looked at a lot of stack overflow questions and answers but i cant seem to find the perfect mix. I know the rep function repeats, and that i can write conditional statements with case_when or ifelse.

df_1 <- df %>%
  repeat row case_when df$food==1 %>%
   mutate (the_first_row (df$weight=prior_w),
          second_row (df$food=0, df$prior_w = NA))

thank you for your help


Solution

  • We may use uncount to replicate the rows and then change the values based on the number of rows by group

    library(dplyr)
    library(tidyr)
    df %>% 
      uncount(1 + (food == 1)) %>% 
      group_by(date) %>%
      mutate(food = if(n() > 1) replace(food, -1, 0) else food,
              weight = if(n() == 2) replace(weight, 1, prior_w[n()]) else weight,
              prior_w = if(n() ==2 ) lag(prior_w) else prior_w) %>%
      ungroup
    

    -output

    # A tibble: 6 × 4
      date        food prior_w weight
      <chr>      <dbl>   <dbl>  <dbl>
    1 2022-01-01     0      NA      5
    2 2022-01-02     0      NA      4
    3 2022-01-03     0      NA      3
    4 2022-01-04     1      NA      2
    5 2022-01-04     0       2      6
    6 2022-01-05     0      NA      4