Home > Software engineering >  How to add a new row in the end of data frame only if the last actual value of the column Z doesn�
How to add a new row in the end of data frame only if the last actual value of the column Z doesn�

Time:10-16

I have a list of several data frames and as the heading states, would like to add a new row (where column Z is "VALUE1") in the end of data frame if the last actual value/string (not counting NA "values") of column Z doesn't contain "VALUE1". I already have a script for adding a new row into the beginning of df if the first value of column Z doesn't contain "VALUE1", but can't quite modify the script into the new one myself.

The aforementioned script I'd like to modify looks following:

for(i in 1:length(df)){
  df[[i]] <- df[[i]] %>%
    filter(!is.na(Z)) %>%
    slice(1) %>%
    mutate(across(col1:col3, ~ 0)) %>%
    filter(!grepl("VALUE1", Z)) %>%
    mutate(Z = "VALUE1") %>%
    bind_rows(., df[[i]])
}

Also if possible, it would be very much welcome if there could be a short comment for each line explaining what happens in the code (not necessary tho) for further learning and understanding. Thank you!

CodePudding user response:

It's a quite strange script. To add a line at end of df's if last is VALUE1, slice by n() instead of by 1, and flip order of bind_rows arguments. Try this:

for(i in 1:length(df)){        
  df[[i]] <- df[[i]] %>%       
    filter(!is.na(Z)) %>%      #filter those rows that are not NA 
    slice(n()) %>%             # select the last (n()) row (in original, select first) we have a new df with 1 row
    mutate(across(col1:col3, ~ 0)) %>%  # set all to zero (since it will be used as new row)
    filter(!grepl("VALUE1", Z)) %>%     # if Z contains VALUE1 the result is a df with 0 row (filter out) 
    mutate(Z = "VALUE1") %>%   # set Z to value1 (if df contains 1 row)
    bind_rows(df[[i]],.)       # paste the new row (. is the pipe placeholder) at end of original data.frame (df[[i]]).
}

# if the step filter(!grepl("VALUE1", Z)) filtered out the row, then bind_rows append a zero row 
# dataframe and the effect is that df[[i]] does not change at all.
  • Related