0

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?

1
  • 1
    Please mark one of the answers below as correct, if any worked for you. Commented Sep 15, 2016 at 11:21

3 Answers 3

4

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.

Sign up to request clarification or add additional context in comments.

3 Comments

do.call(paste0, expand.grid(group, gender, animal))
thank you for you answer. I want to have one vector containing the names and not a data :)
Edited the answer, using Roland's advice
1

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.

3 Comments

I feel like a broken record: "Do not grow an object in a loop. At least pre-allocate to the final size." vect <- character(length(group) * length(gender) * length(animal))
@Roland that's precisely what I told myself
Thank you Eli Korvigo and Roland for your answers.It will work for me. Have a nice day.
0

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"  

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.