Shinzi Katoh
Shinzi Katoh

Reputation: 291

creating a vector with elements fully-crossed from two vectors in r

Suppose I have two vectors.

v1<-c("a","b","c")
v2<-c("x","y","z")

What I wanted to get is a combined vector, which is fully-crossed from one to the other. But before it, each element in the vectors needs to be repeated 3 times.

The final vector I wanted to get is

a a a x x x a a a y y y a a a z z z b b b x x x b b b y y y .....

Other than the for-loop, is there an easy way to make the vector above?

Upvotes: 1

Views: 416

Answers (2)

AntoniosK
AntoniosK

Reputation: 16121

Just an alternative approach to @Heroka 's answer, using dplyr package.

v1<-c("a","b","c")
v2<-c("x","y","z")


library(dplyr)

data.frame(expand.grid(v1,v2)) %>%        # create all combinations
  mutate_each(funs(as.character)) %>%     # transform to character
  arrange(Var1) %>%                       # order by first column
  rowwise() %>%                           # for each row
  do(data.frame(vec=c(rep(.$Var1,3), rep(.$Var2,3)), stringsAsFactors=F))   # create a new vector by repeating the first element 3 times and then the second 3 times


#    vec
# 1    a
# 2    a
# 3    a
# 4    x
# 5    x
# 6    x
# 7    a
# 8    a
# 9    a
# 10   y
# .. ...

Not sure why to prefer using a package instead of base R for this, but just in case someone else has a similar problem (as a part of a bigger process) and he wants to use a dplyr approach.

Upvotes: 0

Heroka
Heroka

Reputation: 13149

Using rep:

#first, create necessary repeats in the two vectors in order to make one cross-product vector
v1_r <- rep(v1, each=3)
v2_r <- rep(v2, 3)
#combine them into one vector
v3 <- as.vector(rbind(v1_r,v2_r))
#add another repeat
v3_r <- rep(v3,each=3)

> v3_r
 [1] "a" "a" "a" "x" "x" "x" "a" "a" "a" "y" "y" "y" "a" "a"
[15] "a" "z" "z" "z" "b" "b" "b" "x" "x" "x" "b" "b" "b" "y"
[29] "y" "y" "b" "b" "b" "z" "z" "z" "c" "c" "c" "x" "x" "x"
[43] "c" "c" "c" "y" "y" "y" "c" "c" "c" "z" "z" "z"

All steps in one line:

v3_r <- rep(as.vector(rbind(rep(v1, each=3),rep(v2,3))),each=3)

Upvotes: 3

Related Questions