3

I've tried a couple ways of doing this problem but am having trouble with how to write it. I think I did the first three steps correctly, but now I have to fill the vector z with numbers from y that are divisible by four, not divisible by three, and have an odd number of digits. I know that I'm using the print function in the wrong way, I'm just at a loss on what else to use ... This is different from that other question because I'm not using a while loop.

#Step 1: Generate 1,000,000 random, uniformly distributed numbers between 0 
#and 1,000,000,000, and name as a vector x. With a seed of 1.
set.seed(1)
x=runif(1000000, min=0, max=1000000000)

#Step 2: Generate a rounded version of x with the name y
y=round(x,digits=0)

#Step 3: Empty vector named z
z=vector("numeric",length=0)

#Step 4: Create for loop that populates z vector with the numbers from y that are divisible by
#4, not divisible by 3, with an odd number of digits. 
for(i in y) {
  if(i%%4==0 && i%%3!=0 && nchar(i,type="chars",allowNA=FALSE,keepNA=NA)%%2!=0){
    print(z,i)
  }
}
L. Smith
  • 55
  • 6
  • to print a concatenated string, use the `paste` function. E.g., `print(paste0(z, i))` – SymbolixAU Oct 02 '16 at 22:09
  • 3
    and for this type of task, you don't (and shouldn't) need to use a loop (a direct subset of the data should work, something like `y[y%%4 == 0 & y%%3 != 0 & nchar(y) %% 2 != 0]` - untested!) – SymbolixAU Oct 02 '16 at 22:10
  • PS you don't need to specify all the optional arguments: `nchar(i)` should work fine – Ben Bolker Oct 02 '16 at 22:22
  • Possible duplicate of [How do I append to a vector using a \`while\` loop?](http://stackoverflow.com/questions/37911963/how-do-i-append-to-a-vector-using-a-while-loop) – 989 Oct 02 '16 at 22:27
  • @SymbolixAU, it actually worked great! I didn't know you could make a direct subset like that. Sadly I have to make a looping function for my homework, and so I can't use this lovely solution T_T. It's good to know for the future that this works better though! – L. Smith Oct 02 '16 at 22:36
  • And @Ben Bolker, thanks for the tips! They really helped make my code neater. – L. Smith Oct 02 '16 at 22:36
  • 1
    You're welcome. I find it odd that in 'introduction to R' courses you're taught about `for` loops, yet they are often discouraged as subsetting is often far more efficient and the *r-way* of doing things – SymbolixAU Oct 02 '16 at 23:39

2 Answers2

3

NOTE: As per @BenBolker's comment, a loop is an inefficient way to solve your problem here. Generally, in R, try to avoid loops where possible to maximise the efficiency of your code. @SymbolixAU has provided an example of doing so here in the comments. Having said that, in aid of helping you learn the ins-and-outs of loops and vectors, here's a solution which only requires a change to one line of your code:

You've got the vector created before the loop, that's a good start. Now, inside your loop, you need to populate that vector. To do so, you've currently got print(z,i), which won't really do too much. What you need to to change the vector itself:

z <- c( z, i )

Should work for you (just replace that print line in your loop).

What's happening here is that we're taking the existing z vector, binding i to the end of it, and making that new vector z again. So every time a value is added, the vector gets a little longer, such that you'll end up with a complete vector.

rosscova
  • 5,430
  • 1
  • 22
  • 35
  • 2
    this works, but it should be noted that "growing" vectors in R is very inefficient; see @SymbolixAU's comment above for a better way – Ben Bolker Oct 02 '16 at 22:16
  • 2
    @BenBolker, I agree, but I get the impression the OP is learning about loops, vectors, etc. So I think the lesson of how to make the code work as it is is helpful. SymbolixAU's answer is certainly more efficient here though. – rosscova Oct 02 '16 at 22:20
  • 1
    yes, I agree. Just *might* be worth mentioning for future reference, or for others who stop by to see the answer. – Ben Bolker Oct 02 '16 at 22:21
  • @BenBolker: Good point. I've added a note to my answer. Hopefully that gets both points across (learning a skill, and learning that the skill you just learned is not the best way to do things)... :) – rosscova Oct 02 '16 at 22:27
  • Yep, @rosscova, this is for an intro to R class and we're learning how to write looping functions. Actually I tried to do this but I keep on getting plus signs next to the code in the console. Should I add something else to the code...? Thanks so much!! – L. Smith Oct 02 '16 at 22:32
  • 1
    I'm not entirely sure what you mean, but it sounds like you might be missing a parentheses or something. If you enter a line of code that's incomplete, R will present you with a new line, to be used to complete your code. eg: `z<-c(z,2` presents a `+` prompt, which is R's way of saying "aaaaand theeeeeeennn..." since it can't complete that code until you close the parentheses. – rosscova Oct 02 '16 at 22:37
  • I think it was something with the parentheses, since I put it all on one line and it worked. Thanks again! – L. Smith Oct 02 '16 at 22:52
1

where you have print put this instead:

z <- append(z, i)
Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
Aschab
  • 1,378
  • 2
  • 14
  • 31