How to insert blank row in specific position with dplyr in r

Viewed 1013

I want to insert blank rows at a specific position in my datafram.

My datafram like this :

dat <- data.frame(group = c(rep('A', 1),rep('B', 4),rep('C', 2), rep('D', 2)))
  group
1     A
2     B
3     B
4     B
5     B
6     C
7     C
8     D
9     D

What I expected is like this:

dat.wanted <- data.frame(group = c(NA,rep('A', 1),NA,rep('B', 4),NA,rep('C', 2), NA,rep('D', 2)))
   group
1   <NA>
2      A
3   <NA>
4      B
5      B
6      B
7      B
8   <NA>
9      C
10     C
11  <NA>
12     D
13     D

And I tried some codes:

# 1  bad codes cause you have to check the row numbers before use add_row() every time
dat.try1 <- dat %>% 
  add_row(.before = 2) %>% 
  add_row(.before = 7) %>% 
  add_row(.before = 10)

# 2 failure
dat.try2 <- dat %>% group_by(group) %>% add_row(.before = 1)

# 3 failure
dat.try3 <- dat %>% group_by(group) %>% mutate(rank = rank(group, ties.method= "first")) %>% ungroup()

dat.try3.2 <- if(dat.try3$rank == 1){dat.try3 <- add_row(dat.try3, .before = 1)}

Is there an easy way to do this?

Any help will be highly appreciated!

3 Answers

An option with group_split and map

library(dplyr)
library(purrr)
dat %>%
    group_split(group) %>% 
    map_dfr(~ .x %>% 
               add_row(group = NA, .before = 1))
# A tibble: 13 x 1
#   group
#   <chr>
# 1 <NA> 
# 2 A    
# 3 <NA> 
# 4 B    
# 5 B    
# 6 B    
# 7 B    
# 8 <NA> 
# 9 C    
#10 C    
#11 <NA> 
#12 D    
#13 D    

Or with data.table

library(data.table)
setDT(dat)[, .(group = c(NA, group)), .(group1 = group)][, group1 := NULL][]

One dplyr option could be:

dat %>%
 group_by(group) %>%
 uncount((row_number() == 1) + 1) %>%
 ungroup() %>%
 mutate(group = replace(group, !duplicated(group), NA))

   group
   <fct>
 1 <NA> 
 2 A    
 3 <NA> 
 4 B    
 5 B    
 6 B    
 7 B    
 8 <NA> 
 9 C    
10 C    
11 <NA> 
12 D    
13 D    

It is not a dplyr solution, but it is an efficient solution working on a vector.

tibble(group = unlist(tapply(dat$group, dat$group, function(x) c(NA, as.character(x)))))
Related