Home > Back-end >  Concatenate unique combinations of elements in a character vector into new vector of strings in R
Concatenate unique combinations of elements in a character vector into new vector of strings in R

Time:04-27

I am trying to find an easy way (preferably a one-liner) to combine and concatenate unique combinations of elements in a character vector into a new vector of strings.

I also want to be able to include any lines of text in the new vector before, in between or after the inserted vector combinations. Combinations should not be repeated in reverse order (e.g. 'x1_x2' but not 'x2_x1'), nor should an element be combined with itself (not 'x1_x1').

Does a quick solution to this exist?

Example of equivalent code for the desired outcome:

vec <- paste0("X", 1:5)
# The underscore signifies any arbitrary line of text
c(
    paste0("_", vec[1], "_", vec[2:5], "_"),
    paste0("_", vec[2], "_", vec[3:5], "_"),
    paste0("_", vec[3], "_", vec[4:5], "_"),
    paste0("_", vec[4], "_", vec[5], "_")
)

'_X1_X2_''_X1_X3_''_X1_X4_''_X1_X5_''_X2_X3_''_X2_X4_''_X2_X5_'
'_X3_X4_''_X3_X5_''_X4_X5_'

CodePudding user response:

Try combn

> sprintf("_%s_", combn(vec, 2, paste0, collapse = "_"))
 [1] "_X1_X2_" "_X1_X3_" "_X1_X4_" "_X1_X5_" "_X2_X3_" "_X2_X4_" "_X2_X5_"
 [8] "_X3_X4_" "_X3_X5_" "_X4_X5_"

> paste0("_", combn(vec, 2, paste0, collapse = "_"), "_")
 [1] "_X1_X2_" "_X1_X3_" "_X1_X4_" "_X1_X5_" "_X2_X3_" "_X2_X4_" "_X2_X5_"
 [8] "_X3_X4_" "_X3_X5_" "_X4_X5_"

CodePudding user response:

You could use

apply(combn(vec, 2), 2, \(x) paste(x, collapse = "_"))
#>  [1] "X1_X2" "X1_X3" "X1_X4" "X1_X5" "X2_X3" "X2_X4" "X2_X5" "X3_X4" "X3_X5" "X4_X5"

CodePudding user response:

Here is another option using arrangements::combinations:

paste0("_",
       apply(arrangements::combinations(x = vec, k = 2), 1, paste, collapse = "_"),
       "_")

#[1] "_X1_X2_" "_X1_X3_" "_X1_X4_" "_X1_X5_" "_X2_X3_" "_X2_X4_" "_X2_X5_" "_X3_X4_" "_X3_X5_" "_X4_X5_"

CodePudding user response:

Here is tidyverse version using crossing:

library(tidyverse)

crossing(x=vec, y=vec) %>% 
  mutate(new = paste0("_",x,"_",y,"_")) %>% 
  group_by(x) %>% 
  filter(row_number()!= 1:unique(parse_number(x))) %>% 
  pull(new)

 [1] "_X1_X2_" "_X1_X3_" "_X1_X4_" "_X1_X5_" "_X2_X3_"
 [6] "_X2_X4_" "_X2_X5_" "_X3_X4_" "_X3_X5_" "_X4_X5_"
  • Related