Mily
Mily

Reputation: 351

loop in loop creating a vector in R

I would like to create a vector using names and numbers.

I have 2 groups : A and B. I have 2 genders: male and female I have 2 animals: dog and cat

Instead of writing a vector containting the name of each group:

vector= c("Amaledog","Afemaledog","Amalecat","Afemalecat","Bmaledog","Bfemaledog","Bmalecat","Bfemalecat")

I would like to use loop in loop:

group=c("A","B")
gender=c("female","male")
animal=c("dog","cat")

for (a in group){
 for (b in gender){
  for (c in animal){
   vector=paste0(a,b,c)
  }
 }
}

But I only obtain : "Bmalecat"

Do you know why? How can I fix this problem?

Upvotes: 0

Views: 94

Answers (3)

akrun
akrun

Reputation: 887881

Here is an option using data.table with the cross join (CJ)

library(data.table)
CJ(group, gender, animal)[, do.call(paste0, .SD)]
#[1] "Afemalecat" "Afemaledog" "Amalecat"   "Amaledog"   "Bfemalecat"
#[6] "Bfemaledog" "Bmalecat"   "Bmaledog"  

Upvotes: 0

Eli Korvigo
Eli Korvigo

Reputation: 10513

You overwrite vector each time, that's the problem. What you probably want to do is

vect <- character(length(group) * length(gender) * length(animal))

i <- 1
for (a in group){
  for (b in gender){
    for (c in animal){
      vect[i] <- paste0(a,b,c)
      i <- i + 1
    }
  }
}

It's important to preallocate the vector in order to avoid a hell lot of (inefficient) reallocation. You should preferably use a vectorised solution.

Upvotes: 1

prateek1592
prateek1592

Reputation: 547

You could just use expand.grid

expand.grid(group=c("A","B"),gender=c("female","male"),animal=c("dog","cat"))

Output :

  group gender animal
1     A female    dog
2     B female    dog
3     A   male    dog
4     B   male    dog
5     A female    cat
6     B female    cat
7     A   male    cat
8     B   male    cat

Edit :

do.call(paste0, expand.grid(group=c("A","B"),gender=c("female","male"),animal=c("dog","cat")))

This should do it, as pointed out in the comments.

Upvotes: 4

Related Questions