0
vec <- c("a: 25", "g: 32", "h: 44", "i: 88", "",
         "a: 22", "i: 53a", "h: 4.2", "g: rt", "",
         "a: zzz", "h: 53", "g: 634", "i: 4", "qq\t5.6", "",
         "a: p", "h: r", "i: 6", "g: 6", "")
beg_pattern <- "a: "; end_element <- ""
grep_pattern1 <- "g: "; grep_pattern2 <- "h: "
desired_reordered_vec <- c("a: 25", "g: 32", "h: 44", "i: 88", "",
                           "a: 22", "i: 53a", "g: rt", "h: 4.2", "",
                           "a: zzz", "g: 634", "h: 53", "i: 4", "qq\t5.6", "",
                           "a: p", "g: 6", "i: 6", "h: r", "")

Essentially, I'd like to re-order my vector such that my "g" element appears before my "h" element within each chunk of elements beginning with beg_pattern and ending with end_element. There is more than one valid solution vector in this example. In my actual data, the patterns are different, save for the end element, and there would be 20-200ish elements-per-chunk. My question has elements of these three questions:How to split vector into list based on consecutive unique values, Split a vector into chunks, Split a vector into three vectors of unequal length in R. But I haven't yet been able to cobble together a solution. I can get my indices this way:

a <- grep("a: ", vec); z <- which("" == vec)
u <- grep("g: ", vec); v <- grep("h: ", vec)

But I'm not sure which, if any, of these will help me perform the desired re-ordering.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563

1 Answers1

1

You could write a function in Base R to do this:

my_sort <- function(x){
  y <- grep('^(g|h):', x)
  x[y] <- x[y][match(sub(":.*", "", x[y]), c("g", "h"))]
  x
}


f <- head(cumsum(vec == ''), -1)
ave(vec, c(f[1], f), FUN = my_sort)
 [1] "a: 25"  "g: 32"  "h: 44"  "i: 88"  ""       "a: 22"  "i: 53a" "g: rt"  "h: 4.2" ""       "a: zzz"
[12] "g: 634" "h: 53"  "i: 4"   "qq\t5.6" ""       "a: p"   "g: 6"   "i: 6"   "h: r"   ""   
Onyambu
  • 67,392
  • 3
  • 24
  • 53