polkas
polkas

Reputation: 4184

splitting vector by a last element in each group

I have a vector and I want to split it by a last element in each group. I have a solution although there should be more and better ones. This seems to be a more rare case than splitting by a first element. Here a last element in each group is a "Overall Score " - some groups contains only this value.

vec <- c("Overall rating ", "Food / Beverage ", "Ambience ", "Service ", 
"Value ", "Overall Score ", "Overall rating ", "Food / Beverage ", 
"Ambience ", "Service ", "Value ", "Overall Score ", "Overall rating ", 
"Food / Beverage ", "Ambience ", "Service ", "Value ", "Overall Score ", 
"Overall rating ", "Food / Beverage ", "Ambience ", "Service ", 
"Value ", "Overall Score ", "Overall rating ", "Food / Beverage ", 
"Ambience ", "Service ", "Value ", "Overall Score ", "Overall Score ", 
"Overall Score ", "Overall Score ", "Overall rating ", "Food / Beverage ", 
"Ambience ", "Service ", "Value ", "Overall Score ", "Overall rating ", 
"Food / Beverage ", "Ambience ", "Service ", "Value ", "Overall Score "
)

#My solution:

overall <- vec == "Overall Score "

rm_last <- function(x) {
  x[-length(x)]
}

> split(vec, rm_last(c(0, cumsum(overall))))
$`0`
[1] "Overall rating "  "Food / Beverage " "Ambience "        "Service "         "Value "           "Overall Score "  

$`1`
[1] "Overall rating "  "Food / Beverage " "Ambience "        "Service "         "Value "           "Overall Score "  

$`2`
[1] "Overall rating "  "Food / Beverage " "Ambience "        "Service "         "Value "           "Overall Score "  

$`3`
[1] "Overall rating "  "Food / Beverage " "Ambience "        "Service "         "Value "           "Overall Score "  

$`4`
[1] "Overall rating "  "Food / Beverage " "Ambience "        "Service "         "Value "           "Overall Score "  

$`5`
[1] "Overall Score "

$`6`
[1] "Overall Score "

$`7`
[1] "Overall Score "

$`8`
[1] "Overall rating "  "Food / Beverage " "Ambience "        "Service "         "Value "           "Overall Score "  

$`9`
[1] "Overall rating "  "Food / Beverage " "Ambience "        "Service "         "Value "           "Overall Score "  

Upvotes: 0

Views: 66

Answers (2)

akrun
akrun

Reputation: 887118

Another option with split and cumsum

split(vec, c(0, cumsum(grepl('Overall Score', vec))[-length(vec)]))

Or using tidyverse

library(dplyr)
library(stringr)
tibble(col1 = vec) %>% 
   mutate(grp = lag(cumsum(str_detect(col1, 'Overall Score')), 
        default = 0)) %>% 
   group_split(grp, .keep = FALSE)

Upvotes: 2

ThomasIsCoding
ThomasIsCoding

Reputation: 101373

You can try the code below with split + cut

split(vec,cut(seq_along(vec),grep("Overall Score",vec)))

Upvotes: 2

Related Questions