1

I'm trying to translate a SAS code containing "retain" statement in R {dplyr}

data verif;
length COMMENTAIRE $20.;
retain COMMENTAIRE ;
    set verif1;
    if top= 1 then COMMENTAIRE = "delete";
    if sample not in ("F","Z") then COMMENTAIRE = "OK";
run;

Is there a way to keep values and change them if a condition is encountered in R like the "retain" statement does it in SAS?

What I'd like to have :

top sample commentaire
0 F ok
1 F delete
0 F delete
0 E ok
0 F ok
1 F delete
0 F delete

To explain it more :
I'd like to keep a value until a new condition is encountered. So in the example above, it means that : If top=1, then values for each row will be "delete" until the condition 'sample not in ("F","Z")' is not encountered. If this condition is encountered, the new value for the following rows will be "OK" until the condition "top=1" is encountered, and then the values for following rows will be "delete" etc.

Hoping it will be easier to understand

Thank you very much

WalliYo_
  • 173
  • 7
  • 1
    It's easier to help you if you include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. Since code translation is off topic, describe what you are trying to do in words since not all R users are familiar with every SAS statement. – MrFlick Mar 13 '23 at 15:12
  • 1
    You need to explain what it is you are actually trying to do. The SAS code by itself does not explain what you are actually trying to calculate. Especially as you do not appear to have any variables that indicate either grouping or ordering of the observations. – Tom Mar 13 '23 at 16:10

1 Answers1

2

I think we could accomplish this by setting commentaire values based on the two conditions (plus a special case for the first row before any conditions have been met), leavings other rows as NA, then using tidyr::fill to fill down (the default) over the NAs.

library(tidyverse)
verif %>% 
   mutate(commentaire = case_when(top == 1 ~ "delete", 
                                  !sample %in% c("F","Z") ~ "ok",
                                  row_number() == 1 ~ "ok", 
                                  TRUE ~ NA_character_)) %>% 
   fill(commentaire) 

Result

  top sample commentaire
1   0      F          ok
2   1      F      delete
3   0      F      delete
4   0      E          ok
5   0      F          ok
6   1      F      delete
7   0      F      delete

verif <- structure(list(top = c(0L, 1L, 0L, 0L, 0L, 1L, 0L), 
                        sample = c("F", "F", "F", "E", "F", "F", "F")), 
                   class = "data.frame", row.names = c(NA, -7L))
Jon Spring
  • 55,165
  • 4
  • 35
  • 53