Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add rows to a data-frame based on values in one of the columns

Tags:

r

dplyr

tidyverse

Currently the data-frame looks something like this:

   Scenario Month            A            B            C
         1     1 -0.593186301  1.045550808 -0.593816304
         1     2  0.178626141  2.043084432  0.111370583
         1     3  1.205779717 -0.324083723 -1.397716949
         2     1  0.933615199  0.052647056 -0.656486153
         2     2  1.647291688 -1.065793671  0.799040546
         2     3  1.613663101 -1.955567231 -1.817457972
         3     1 -0.621991775  1.634069402 -1.404981646
         3     2 -1.899326887 -0.836322394 -1.826351541
         3     3  0.164235141 -1.160701812  1.238246459 

I'd like to add rows on top of the row where Month = 1 as below. I know dplyr has an add_rows function but I'd like to add rows based on a condition. Any help is hugely appreciated.


    Scenario Month       A            B            C
      0                                             
      1     1 -0.593186301  1.045550808 -0.593816304
      1     2  0.178626141  2.043084432  0.111370583
      1     3  1.205779717 -0.324083723 -1.397716949
      0                                             
      2     1  0.933615199  0.052647056 -0.656486153
      2     2  1.647291688 -1.065793671  0.799040546
      2     3  1.613663101 -1.955567231 -1.817457972
      0                                             
      3     1 -0.621991775  1.634069402 -1.404981646
      3     2 -1.899326887 -0.836322394 -1.826351541
      3     3  0.164235141 -1.160701812  1.238246459
like image 283
Dal Avatar asked Jan 01 '23 08:01

Dal


2 Answers

A solution using tidyverse.

library(tidyverse)

dat2 <- dat %>%
  split(f = .$Scenario) %>%
  map_dfr(~bind_rows(tibble(Scenario = 0), .x))
dat2
# # A tibble: 12 x 5
#    Scenario Month       A        B       C
#       <dbl> <int>   <dbl>    <dbl>   <dbl>
#  1        0    NA  NA      NA       NA    
#  2        1     1  -0.593   1.05    -0.594
#  3        1     2   0.179   2.04     0.111
#  4        1     3   1.21   -0.324   -1.40 
#  5        0    NA  NA      NA       NA    
#  6        2     1   0.934   0.0526  -0.656
#  7        2     2   1.65   -1.07     0.799
#  8        2     3   1.61   -1.96    -1.82 
#  9        0    NA  NA      NA       NA    
# 10        3     1  -0.622   1.63    -1.40 
# 11        3     2  -1.90   -0.836   -1.83 
# 12        3     3   0.164  -1.16     1.24 

DATA

dat <- read.table(text = "Scenario Month            A            B            C
         1     1 -0.593186301  1.045550808 -0.593816304
         1     2  0.178626141  2.043084432  0.111370583
         1     3  1.205779717 -0.324083723 -1.397716949
         2     1  0.933615199  0.052647056 -0.656486153
         2     2  1.647291688 -1.065793671  0.799040546
         2     3  1.613663101 -1.955567231 -1.817457972
         3     1 -0.621991775  1.634069402 -1.404981646
         3     2 -1.899326887 -0.836322394 -1.826351541
         3     3  0.164235141 -1.160701812  1.238246459 ",
                  header = TRUE)
like image 159
www Avatar answered Jan 05 '23 07:01

www


Somehow add_row doesn't take multiple values to its .before parameter.

One way is to split the dataframe wherever Month = 1 and then for each dataframe add a row using add_row above Month = 1.

library(tidyverse)
map_df(split(df, cumsum(df$Month == 1)), 
     ~ add_row(., Scenario = 0, .before = which(.$Month == 1)))

#   Scenario Month          A           B          C
#1         0    NA         NA          NA         NA
#2         1     1 -0.5931863  1.04555081 -0.5938163
#3         1     2  0.1786261  2.04308443  0.1113706
#4         1     3  1.2057797 -0.32408372 -1.3977169
#5         0    NA         NA          NA         NA
#6         2     1  0.9336152  0.05264706 -0.6564862
#7         2     2  1.6472917 -1.06579367  0.7990405
#8         2     3  1.6136631 -1.95556723 -1.8174580
#9         0    NA         NA          NA         NA
#10        3     1 -0.6219918  1.63406940 -1.4049816
#11        3     2 -1.8993269 -0.83632239 -1.8263515
#12        3     3  0.1642351 -1.16070181  1.2382465
like image 29
Ronak Shah Avatar answered Jan 05 '23 08:01

Ronak Shah