Adding elements to vector based on condition

x <- c(
  "W10ABCD12345xyz                         This is a header", 
  "R10ABCD12345xyz5000Apple",
  "R10ABCD12345xyz8999Banana",
  "W11EFGH12345xyz                         This is a header",
  "R11EFGH12345xyz5000Apple",
  "R11EFGH12345xyz8999Banana",
  "X10PQRS12345xyz                         This is a header",
  "R10PQRS12345xyz5000Apple",
  "W10GOOD12345xyz                         This is a header",
  "R10GOOD12345xyz5000Apple",
  "R10GOOD12345xyz8999Banana"
)

The vector x can be grouped by the header lines; each group has sub-lines. How can I add lines only to the group whose header starts with "W10"?

Notice that all the sub-lines of a given group have common elements from the first letter to "xyz". Also, "12345" is common.

The new line I want to add should be something like paste0(common_elements, "NAME", "12345")

wanted <- c(
  "W10ABCD12345xyz                         This is a header", 
  "R10ABCD12345xyz5000Apple",
  "R10ABCD12345xyz8999Banana",
  "R10ABCD12345xyzNAME12345", # new line wanted
  "W11EFGH12345xyz                         This is a header",
  "R11EFGH12345xyz5000Apple",
  "R11EFGH12345xyz8999Banana",
  "X10PQRS12345xyz                         This is a header",
  "R10PQRS12345xyz5000Apple",
  "W10GOOD12345xyz                         This is a header",
  "R10GOOD12345xyz5000Apple",
  "R10GOOD12345xyz8999Banana",
  "R10GOOD12345xyzNAME12345" # new line wanted
)

Hi @budugulo. Below is one way to achieve the desired output using the tidyverse.

library(tidyverse)

# data frame of original vector, which identifies header row and group
base_items = data.frame(vec = x) |>
  mutate(check = ifelse(str_detect(vec, 'header'), 
                        substr(vec,1,3), 
                        NA)
  ) |>
  mutate(group = ifelse(!is.na(check), 1, 0),
         group = cumsum(group),
         group = ifelse(is.na(check), group + 0.1, group))

# create new items based on base_items
new_items = base_items |>
  mutate(common = substr(vec,1,15)) |> 
  mutate(new = ifelse(check == 'W10', 
                      paste0(lead(common), 'NAME12345'),
                      NA)
         ) |>
  filter(!is.na(new)) |> 
  mutate(group = group + 0.1) |>
  distinct(group, new) |> 
  rename(vec = new)

# combine and arrange
final = bind_rows(base_items, new_items) |>
  arrange(group, vec) |>
  pull(vec)

final
#>  [1] "W10ABCD12345xyz                         This is a header"
#>  [2] "R10ABCD12345xyz5000Apple"                                
#>  [3] "R10ABCD12345xyz8999Banana"                               
#>  [4] "R10ABCD12345xyzNAME12345"                                
#>  [5] "W11EFGH12345xyz                         This is a header"
#>  [6] "R11EFGH12345xyz5000Apple"                                
#>  [7] "R11EFGH12345xyz8999Banana"                               
#>  [8] "X10PQRS12345xyz                         This is a header"
#>  [9] "R10PQRS12345xyz5000Apple"                                
#> [10] "W10GOOD12345xyz                         This is a header"
#> [11] "R10GOOD12345xyz5000Apple"                                
#> [12] "R10GOOD12345xyz8999Banana"                               
#> [13] "R10GOOD12345xyzNAME12345"

Created on 2024-01-06 with reprex v2.0.2

Hi @budugulo

here is a base R approach

x <- c(
  "W10ABCD12345xyz                         This is a header", 
  "R10ABCD12345xyz5000Apple",
  "R10ABCD12345xyz8999Banana",
  "W11EFGH12345xyz                         This is a header",
  "R11EFGH12345xyz5000Apple",
  "R11EFGH12345xyz8999Banana",
  "X10PQRS12345xyz                         This is a header",
  "R10PQRS12345xyz5000Apple",
  "W10GOOD12345xyz                         This is a header",
  "R10GOOD12345xyz5000Apple",
  "R10GOOD12345xyz8999Banana"
)
headerIndex <- which(grepl(pattern = ".*header.*", x = x))
repeatHeader <- c(diff(headerIndex), length(x)-headerIndex[length(headerIndex)]+1)
group <- rep(headerIndex, repeatHeader)
a <- by(data = x, 
        INDICES = group,
        FUN = function(x){
          newEntry <- paste0(
            paste0(
              Reduce(intersect, 
                     lapply(x[2:length(x)],
                            function(x){
                              unlist(strsplit(x,""))})
                     )
              ,collapse = ""), 
            "NAME12345", collapse = "")
          x <- c(x,newEntry)
        }, 
        simplify = TRUE)

result <- unlist(a, use.names = FALSE)
result

If it fits what you want i will add a proper comment explaining what is going on :smiley:

Many thanks, both!

@scottyd22 your code works perfectly :slight_smile: Thanks again! One question: suppose instead of NAME, the new string is 0****. In that case, arrange() does not put the new line as the last line. How can I ensure the new line always comes at last for each group?

@vedoa your code almost generates what I want. The only issue is that the new line misses some strings. For example, instead of producing R10GOOD12345xyzNAME12345 it generates
R10GOD2345xyzNAME12345 . Please do add a comment! Thanks!

@budugulo good catch. You can update the mutate in new_items to be + 0.2. Then, when arranged by group, these will always move to the bottom. Below is an example when NAME is replaced with 0000.

new_items = base_items |>
  mutate(common = substr(vec,1,15)) |> 
  mutate(new = ifelse(check == 'W10', 
                      paste0(lead(common), '000012345'), # UPDATE to 0000...
                      NA)
         ) |>
  filter(!is.na(new)) |> 
  mutate(group = group + 0.2) |> # UPDATE
  distinct(group, new) |> 
  rename(vec = new)

# combine and arrange
final = bind_rows(base_items, new_items) |>
  arrange(group, vec) |>
  pull(vec)

final
#>  [1] "W10ABCD12345xyz                         This is a header"
#>  [2] "R10ABCD12345xyz5000Apple"                                
#>  [3] "R10ABCD12345xyz8999Banana"                               
#>  [4] "R10ABCD12345xyz000012345"                                
#>  [5] "W11EFGH12345xyz                         This is a header"
#>  [6] "R11EFGH12345xyz5000Apple"                                
#>  [7] "R11EFGH12345xyz8999Banana"                               
#>  [8] "X10PQRS12345xyz                         This is a header"
#>  [9] "R10PQRS12345xyz5000Apple"                                
#> [10] "W10GOOD12345xyz                         This is a header"
#> [11] "R10GOOD12345xyz5000Apple"                                
#> [12] "R10GOOD12345xyz8999Banana"                               
#> [13] "R10GOOD12345xyz000012345"
1 Like

Hi @budugulo ,

here is a working code with proper comments

x <- c(
  "W10ABCD12345xyz                         This is a header", 
  "R10ABCD12345xyz5000Apple",
  "R10ABCD12345xyz8999Banana",
  "W11EFGH12345xyz                         This is a header",
  "R11EFGH12345xyz5000Apple",
  "R11EFGH12345xyz8999Banana",
  "X10PQRS12345xyz                         This is a header",
  "R10PQRS12345xyz5000Apple",
  "W10GOOD12345xyz                         This is a header",
  "R10GOOD12345xyz5000Apple",
  "R10GOOD12345xyz8999Banana"
)
# Step 0
headerIndex <- which(grepl(pattern = ".*header.*", x = x))
repeatHeader <- c(diff(headerIndex), length(x)-headerIndex[length(headerIndex)]+1)
group <- rep(headerIndex, repeatHeader)

yourInput <- "NAME12345"

a <- by(data = x, 
        INDICES = group,
        FUN = function(y){
          # Step 1
          if(!(substr(x = y[1], start = 1, stop = 3) %in% c("W10"))){
            return(y)
          }else{
            # Step 2
            minChar <- min(nchar(y))
            # Step 3
            temp <- substr(x = y, start = 4, stop = minChar)
            # Step 4
            prepareComparison <- lapply(temp, 
                                        function(x){
                                          unlist(strsplit(x, split = ""))
                                        })
            # Step 5
            minCommonElements <- min(unlist(lapply(prepareComparison[2:length(prepareComparison)], 
                                        function(z){
                                          which.min(prepareComparison[[1]] == z)-1
                                        })))
            # Step 6
            commonString <- paste0(prepareComparison[[1]][1:minCommonElements], collapse = "")
            # Step 7
            startString <- substr(x = y[2], start = 1, stop = 3)
            # Step 8
            newEntry <- paste0(startString, commonString, yourInput)
            # Step 9
            y <- c(y, newEntry)
          }
        }, 
        simplify = TRUE)

result <- unlist(a, use.names = FALSE)
data.frame(result)

# result
# 1  W10ABCD12345xyz                         This is a header
# 2                                  R10ABCD12345xyz5000Apple
# 3                                 R10ABCD12345xyz8999Banana
# 4                                  R10ABCD12345xyzNAME12345
# 5  W11EFGH12345xyz                         This is a header
# 6                                  R11EFGH12345xyz5000Apple
# 7                                 R11EFGH12345xyz8999Banana
# 8  X10PQRS12345xyz                         This is a header
# 9                                  R10PQRS12345xyz5000Apple
# 10                                 R10PQRS12345xyzNAME12345
# 11 W10GOOD12345xyz                         This is a header
# 12                                 R10GOOD12345xyz5000Apple
# 13                                R10GOOD12345xyz8999Banana
# 14                                 R10GOOD12345xyzNAME12345

Steps

  1. Get index of header rows. Repeat them so many times until the next header. This will be used to make a group for the by function. Now for every group:
  2. If the header doesn't start with W10 give the group back as is (you can easily extend it if you need it by adding c("W10", "X10") for example)
  3. Find the smalest string length
  4. Substring everything from the 4 character to the length of step 2 (since the group differs by the first 3 characters)
  5. Make strings to character vectors
  6. Find the index of last matching character
  7. Extract the common string
  8. Add the starting string (not the header)
  9. Glue begining, common string and the input that you want (NAME12345)
  10. Add to end of the group

Thanks for poinitng the failures out.

1 Like

Since I imagine there could be folks who might be curious about a tidyverse-only approach and benefit from a detailed walk-through illustrating the intermediate steps involved, I thought I'd add another tidyverse alternative to the one @scottyd22 shared:

# original vector
x <- c(
  "W10ABCD12345xyz                         This is a header", 
  "R10ABCD12345xyz5000Apple",
  "R10ABCD12345xyz8999Banana",
  "W11EFGH12345xyz                         This is a header",
  "R11EFGH12345xyz5000Apple",
  "R11EFGH12345xyz8999Banana",
  "X10PQRS12345xyz                         This is a header",
  "R10PQRS12345xyz5000Apple",
  "W10GOOD12345xyz                         This is a header",
  "R10GOOD12345xyz5000Apple",
  "R10GOOD12345xyz8999Banana"
)
# load tidyverse for easy access to the dplyr and stringr functions used below
library(tidyverse)
# convert x to tibble and use 'separate()' to split off header label from
# original value by "breaking" value wherever it contains white space, but use
# the 'extra' parameter to keep only the word "This" from the original header
# label
x |> 
  tibble() |>
  separate(x, into = c('value', 'header'), remove = F, extra = 'drop') |> 
  relocate(value, header)
#> Warning: Expected 2 pieces. Missing pieces filled with `NA` in 7 rows [2, 3, 5, 6, 8,
#> 10, 11].

#> # A tibble: 11 × 3
#>    value                     header x                                           
#>    <chr>                     <chr>  <chr>                                       
#>  1 W10ABCD12345xyz           This   W10ABCD12345xyz                         Thi…
#>  2 R10ABCD12345xyz5000Apple  <NA>   R10ABCD12345xyz5000Apple                    
#>  3 R10ABCD12345xyz8999Banana <NA>   R10ABCD12345xyz8999Banana                   
#>  4 W11EFGH12345xyz           This   W11EFGH12345xyz                         Thi…
#>  5 R11EFGH12345xyz5000Apple  <NA>   R11EFGH12345xyz5000Apple                    
#>  6 R11EFGH12345xyz8999Banana <NA>   R11EFGH12345xyz8999Banana                   
#>  7 X10PQRS12345xyz           This   X10PQRS12345xyz                         Thi…
#>  8 R10PQRS12345xyz5000Apple  <NA>   R10PQRS12345xyz5000Apple                    
#>  9 W10GOOD12345xyz           This   W10GOOD12345xyz                         Thi…
#> 10 R10GOOD12345xyz5000Apple  <NA>   R10GOOD12345xyz5000Apple                    
#> 11 R10GOOD12345xyz8999Banana <NA>   R10GOOD12345xyz8999Banana
# save result
table1 <- 
  x |> 
  tibble() |>
  separate(x, into = c('value', 'header'), remove = F) |> 
  relocate(value, header)
#> Warning: Expected 2 pieces. Additional pieces discarded in 4 rows [1, 4, 7, 9].
#> Expected 2 pieces. Missing pieces filled with `NA` in 7 rows [2, 3, 5, 6, 8,
#> 10, 11].
# convert header column to logical flag for presence of header
table1 |> 
  mutate(header = !is.na(header))
#> # A tibble: 11 × 3
#>    value                     header x                                           
#>    <chr>                     <lgl>  <chr>                                       
#>  1 W10ABCD12345xyz           TRUE   W10ABCD12345xyz                         Thi…
#>  2 R10ABCD12345xyz5000Apple  FALSE  R10ABCD12345xyz5000Apple                    
#>  3 R10ABCD12345xyz8999Banana FALSE  R10ABCD12345xyz8999Banana                   
#>  4 W11EFGH12345xyz           TRUE   W11EFGH12345xyz                         Thi…
#>  5 R11EFGH12345xyz5000Apple  FALSE  R11EFGH12345xyz5000Apple                    
#>  6 R11EFGH12345xyz8999Banana FALSE  R11EFGH12345xyz8999Banana                   
#>  7 X10PQRS12345xyz           TRUE   X10PQRS12345xyz                         Thi…
#>  8 R10PQRS12345xyz5000Apple  FALSE  R10PQRS12345xyz5000Apple                    
#>  9 W10GOOD12345xyz           TRUE   W10GOOD12345xyz                         Thi…
#> 10 R10GOOD12345xyz5000Apple  FALSE  R10GOOD12345xyz5000Apple                    
#> 11 R10GOOD12345xyz8999Banana FALSE  R10GOOD12345xyz8999Banana

table2 <- 
  table1 |> 
  mutate(header = !is.na(header))
# extract prefix from original vector value and isolate prefixes of header
# values
table2 |> 
  separate(content, into = c('prefix', 'base'), sep = 3) |> 
  mutate(header_prefix = if_else(header, prefix, NA), .after = header) 
#> # A tibble: 11 × 5
#>    prefix base                   header header_prefix x                         
#>    <chr>  <chr>                  <lgl>  <chr>         <chr>                     
#>  1 W10    ABCD12345xyz           TRUE   W10           W10ABCD12345xyz          …
#>  2 R10    ABCD12345xyz5000Apple  FALSE  <NA>          R10ABCD12345xyz5000Apple  
#>  3 R10    ABCD12345xyz8999Banana FALSE  <NA>          R10ABCD12345xyz8999Banana 
#>  4 W11    EFGH12345xyz           TRUE   W11           W11EFGH12345xyz          …
#>  5 R11    EFGH12345xyz5000Apple  FALSE  <NA>          R11EFGH12345xyz5000Apple  
#>  6 R11    EFGH12345xyz8999Banana FALSE  <NA>          R11EFGH12345xyz8999Banana 
#>  7 X10    PQRS12345xyz           TRUE   X10           X10PQRS12345xyz          …
#>  8 R10    PQRS12345xyz5000Apple  FALSE  <NA>          R10PQRS12345xyz5000Apple  
#>  9 W10    GOOD12345xyz           TRUE   W10           W10GOOD12345xyz          …
#> 10 R10    GOOD12345xyz5000Apple  FALSE  <NA>          R10GOOD12345xyz5000Apple  
#> 11 R10    GOOD12345xyz8999Banana FALSE  <NA>          R10GOOD12345xyz8999Banana

table3 <- 
  table2 |> 
  separate(content, into = c('prefix', 'base'), sep = 3) |> 
  mutate(header_prefix = if_else(header, prefix, NA), .after = header) 
# use 'fill()' to transmit group header prefix to non-header values, then 
# extract common value
table3 |> 
  fill(header_prefix) |> 
  mutate(common = base |> str_extract('^.+xyz'), .after = header_prefix) 
#> # A tibble: 11 × 6
#>    prefix base                   header header_prefix common       x            
#>    <chr>  <chr>                  <lgl>  <chr>         <chr>        <chr>        
#>  1 W10    ABCD12345xyz           TRUE   W10           ABCD12345xyz W10ABCD12345…
#>  2 R10    ABCD12345xyz5000Apple  FALSE  W10           ABCD12345xyz R10ABCD12345…
#>  3 R10    ABCD12345xyz8999Banana FALSE  W10           ABCD12345xyz R10ABCD12345…
#>  4 W11    EFGH12345xyz           TRUE   W11           EFGH12345xyz W11EFGH12345…
#>  5 R11    EFGH12345xyz5000Apple  FALSE  W11           EFGH12345xyz R11EFGH12345…
#>  6 R11    EFGH12345xyz8999Banana FALSE  W11           EFGH12345xyz R11EFGH12345…
#>  7 X10    PQRS12345xyz           TRUE   X10           PQRS12345xyz X10PQRS12345…
#>  8 R10    PQRS12345xyz5000Apple  FALSE  X10           PQRS12345xyz R10PQRS12345…
#>  9 W10    GOOD12345xyz           TRUE   W10           GOOD12345xyz W10GOOD12345…
#> 10 R10    GOOD12345xyz5000Apple  FALSE  W10           GOOD12345xyz R10GOOD12345…
#> 11 R10    GOOD12345xyz8999Banana FALSE  W10           GOOD12345xyz R10GOOD12345…

table4 <- 
  table3 |> 
  fill(header_prefix) |> 
  mutate(common = base |> str_extract('^.+xyz'), .after = header_prefix) 
# extract header prefixes of interest and use common value to create desired new
# base values
table4 |> 
  distinct(header_prefix, common) |> 
  filter(header_prefix == 'W10') |> 
  mutate(base = common |> str_c('NAME12345'))
#> # A tibble: 2 × 3
#>   header_prefix common       base            
#>   <chr>         <chr>        <chr>           
#> 1 W10           ABCD12345xyz ABCD12345xyzNAME12345
#> 2 W10           GOOD12345xyz GOOD12345xyzNAME12345

new_rows <- 
  table4 |> 
  distinct(header_prefix, common) |> 
  filter(header_prefix == 'W10') |> 
  mutate(base = common |> str_c('NAME12345'))
# attach new rows to current table
table4 |> 
  bind_rows(new_rows)
#> # A tibble: 13 × 6
#>    prefix base                   header header_prefix common       x            
#>    <chr>  <chr>                  <lgl>  <chr>         <chr>        <chr>        
#>  1 W10    ABCD12345xyz           TRUE   W10           ABCD12345xyz W10ABCD12345…
#>  2 R10    ABCD12345xyz5000Apple  FALSE  W10           ABCD12345xyz R10ABCD12345…
#>  3 R10    ABCD12345xyz8999Banana FALSE  W10           ABCD12345xyz R10ABCD12345…
#>  4 W11    EFGH12345xyz           TRUE   W11           EFGH12345xyz W11EFGH12345…
#>  5 R11    EFGH12345xyz5000Apple  FALSE  W11           EFGH12345xyz R11EFGH12345…
#>  6 R11    EFGH12345xyz8999Banana FALSE  W11           EFGH12345xyz R11EFGH12345…
#>  7 X10    PQRS12345xyz           TRUE   X10           PQRS12345xyz X10PQRS12345…
#>  8 R10    PQRS12345xyz5000Apple  FALSE  X10           PQRS12345xyz R10PQRS12345…
#>  9 W10    GOOD12345xyz           TRUE   W10           GOOD12345xyz W10GOOD12345…
#> 10 R10    GOOD12345xyz5000Apple  FALSE  W10           GOOD12345xyz R10GOOD12345…
#> 11 R10    GOOD12345xyz8999Banana FALSE  W10           GOOD12345xyz R10GOOD12345…
#> 12 <NA>   ABCD12345xyzNAME12345  NA     W10           ABCD12345xyz <NA>         
#> 13 <NA>   GOOD12345xyzNAME12345  NA     W10           GOOD12345xyz <NA>

table5 <- 
  table4 |> 
  bind_rows(new_rows)
# use row order to capture order of groups in original vector
table5 |> 
  mutate(row = row_number(), .after = common) |> 
  group_by(header_prefix, common) |> 
  mutate(group_order = min(row), .after = common) |> 
  ungroup()
#> # A tibble: 13 × 8
#>    prefix base               header header_prefix common group_order   row x    
#>    <chr>  <chr>              <lgl>  <chr>         <chr>        <int> <int> <chr>
#>  1 W10    ABCD12345xyz       TRUE   W10           ABCD1…           1     1 W10A…
#>  2 R10    ABCD12345xyz5000A… FALSE  W10           ABCD1…           1     2 R10A…
#>  3 R10    ABCD12345xyz8999B… FALSE  W10           ABCD1…           1     3 R10A…
#>  4 W11    EFGH12345xyz       TRUE   W11           EFGH1…           4     4 W11E…
#>  5 R11    EFGH12345xyz5000A… FALSE  W11           EFGH1…           4     5 R11E…
#>  6 R11    EFGH12345xyz8999B… FALSE  W11           EFGH1…           4     6 R11E…
#>  7 X10    PQRS12345xyz       TRUE   X10           PQRS1…           7     7 X10P…
#>  8 R10    PQRS12345xyz5000A… FALSE  X10           PQRS1…           7     8 R10P…
#>  9 W10    GOOD12345xyz       TRUE   W10           GOOD1…           9     9 W10G…
#> 10 R10    GOOD12345xyz5000A… FALSE  W10           GOOD1…           9    10 R10G…
#> 11 R10    GOOD12345xyz8999B… FALSE  W10           GOOD1…           9    11 R10G…
#> 12 <NA>   ABCD12345xyzNAME1… NA     W10           ABCD1…           1    12 <NA> 
#> 13 <NA>   GOOD12345xyzNAME1… NA     W10           GOOD1…           9    13 <NA>

table6 <- 
  table5 |> 
  mutate(row = row_number(), .after = common) |> 
  group_by(header_prefix, common) |> 
  mutate(group_order = min(row), .after = common) |> 
  ungroup()
# move new rows into desired final locations
table6 |> 
  arrange(group_order, row)
#> # A tibble: 13 × 8
#>    prefix base               header header_prefix common group_order   row x    
#>    <chr>  <chr>              <lgl>  <chr>         <chr>        <int> <int> <chr>
#>  1 W10    ABCD12345xyz       TRUE   W10           ABCD1…           1     1 W10A…
#>  2 R10    ABCD12345xyz5000A… FALSE  W10           ABCD1…           1     2 R10A…
#>  3 R10    ABCD12345xyz8999B… FALSE  W10           ABCD1…           1     3 R10A…
#>  4 <NA>   ABCD12345xyzNAME1… NA     W10           ABCD1…           1    12 <NA> 
#>  5 W11    EFGH12345xyz       TRUE   W11           EFGH1…           4     4 W11E…
#>  6 R11    EFGH12345xyz5000A… FALSE  W11           EFGH1…           4     5 R11E…
#>  7 R11    EFGH12345xyz8999B… FALSE  W11           EFGH1…           4     6 R11E…
#>  8 X10    PQRS12345xyz       TRUE   X10           PQRS1…           7     7 X10P…
#>  9 R10    PQRS12345xyz5000A… FALSE  X10           PQRS1…           7     8 R10P…
#> 10 W10    GOOD12345xyz       TRUE   W10           GOOD1…           9     9 W10G…
#> 11 R10    GOOD12345xyz5000A… FALSE  W10           GOOD1…           9    10 R10G…
#> 12 R10    GOOD12345xyz8999B… FALSE  W10           GOOD1…           9    11 R10G…
#> 13 <NA>   GOOD12345xyzNAME1… NA     W10           GOOD1…           9    13 <NA>

table7 <- 
  table6 |> 
  arrange(group_order, row)
# use 'fill()' to transmit correct prefixes to new rows, and then use prefixes
# to create desired new vector values
table7 |> 
  fill(prefix) |> 
  mutate(x = if_else(is.na(x), prefix |> str_c(base), x))
#> # A tibble: 13 × 8
#>    prefix base               header header_prefix common group_order   row x    
#>    <chr>  <chr>              <lgl>  <chr>         <chr>        <int> <int> <chr>
#>  1 W10    ABCD12345xyz       TRUE   W10           ABCD1…           1     1 W10A…
#>  2 R10    ABCD12345xyz5000A… FALSE  W10           ABCD1…           1     2 R10A…
#>  3 R10    ABCD12345xyz8999B… FALSE  W10           ABCD1…           1     3 R10A…
#>  4 R10    ABCD12345xyzNAME1… NA     W10           ABCD1…           1    12 R10A…
#>  5 W11    EFGH12345xyz       TRUE   W11           EFGH1…           4     4 W11E…
#>  6 R11    EFGH12345xyz5000A… FALSE  W11           EFGH1…           4     5 R11E…
#>  7 R11    EFGH12345xyz8999B… FALSE  W11           EFGH1…           4     6 R11E…
#>  8 X10    PQRS12345xyz       TRUE   X10           PQRS1…           7     7 X10P…
#>  9 R10    PQRS12345xyz5000A… FALSE  X10           PQRS1…           7     8 R10P…
#> 10 W10    GOOD12345xyz       TRUE   W10           GOOD1…           9     9 W10G…
#> 11 R10    GOOD12345xyz5000A… FALSE  W10           GOOD1…           9    10 R10G…
#> 12 R10    GOOD12345xyz8999B… FALSE  W10           GOOD1…           9    11 R10G…
#> 13 R10    GOOD12345xyzNAME1… NA     W10           GOOD1…           9    13 R10G…

table8 <- 
  table7 |> 
  fill(prefix) |> 
  mutate(x = if_else(is.na(x), prefix |> str_c(base), x))
# extract new version of original vector
table8 |> 
  pull(x)
#>  [1] "W10ABCD12345xyz                         This is a header"
#>  [2] "R10ABCD12345xyz5000Apple"                                
#>  [3] "R10ABCD12345xyz8999Banana"                               
#>  [4] "R10ABCD12345xyzNAME12345"                                     
#>  [5] "W11EFGH12345xyz                         This is a header"
#>  [6] "R11EFGH12345xyz5000Apple"                                
#>  [7] "R11EFGH12345xyz8999Banana"                               
#>  [8] "X10PQRS12345xyz                         This is a header"
#>  [9] "R10PQRS12345xyz5000Apple"                                
#> [10] "W10GOOD12345xyz                         This is a header"
#> [11] "R10GOOD12345xyz5000Apple"                                
#> [12] "R10GOOD12345xyz8999Banana"                               
#> [13] "R10GOOD12345xyzNAME12345"

Created on 2024-01-07 with reprex v2.0.2

1 Like

There is another solution then: start by extending the vector by the needed size, e.g. by push_back() or resize() keeping the existing elements. Then move all elements last to first to their new positions. Then copy the elements to be inserted from their possibly new positions to the "gap". No temporaries needed.

Yeah C++ unfortunately doesn't have any standard solution for this as far as I know, but it's also extremely uncommon to insert parts of containers into itself.
9apps

This topic was automatically closed 42 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.