0

I want to write six temp data files from my original data keeping the following variables:

  • temp1: v1-v18
  • temp2: v1-v5 v19-v31
  • temp3: v1-v5 v32-v44
  • temp4: v1-v5 v45-v57
  • temp5: v1-v5 v58-v70
  • temp6: v1-v5 v71-v84

I have tried the following:

forvalues i =1(1)6 { 
    preserve
    local j = 6 + (`i'-1)*13
    local k = `j'+12
    keep v1-v18 if `j'==6
    keep v1-v5 v`i'-v`k' if `i'>6 & `j'<71
    keep v1-v5 v71-v84 if `j'==71
    export delimited using temp`i'.csv, delimiter(";") novarnames replace
    restore 
}

I get an invalid syntax error. The problem lies with the keep statements. Specifically the if condition with a local macro seems to be against syntax rules.

DirkSa
  • 5
  • 1
  • Please be sure to up-vote answers that are helpful and flag answers as accepted if they provide a solution. This gives us points and encourages the community to grow! – n8. Jun 03 '16 at 17:48
  • @ander2ed gives a very good diagnosis but it follows from the `help` for `keep` that you can can `keep` a _varlist_ or `keep` certain observations using an `if` qualifier **but not both at the same time**. That is almost certainly the immediate problem (although you don't provide a reproducible example, as your code depends on your datasets). There is no problem with combining an `if` qualifier and local macros so long as the syntax is legal otherwise. – Nick Cox Jun 03 '16 at 17:48
  • Not the question, but a situation in which six individual `keep` statements would have been much shorter and much quicker to write. – Nick Cox Jun 03 '16 at 18:21

1 Answers1

1

I think part of your confusion is due to misunderstanding the if qualifier vs the if command.

The if command evaluates an expression: if that expression is true, it executes what follows. The if command should be used to evaluate a single expression, in this case, the value of a macro.

You might use an if qualifier, for example, when you want to regress y x if x > 2 or replace x = . if x <= 2 etc. See here for a short description.

Your syntax has other issues too. You cannot have code following on the same line as the open brace in your forvalues loop, or again on the same line as your closing brace. You also use the local i to condition your keep. I think you mean to use j here, as i simply serves to iterate the loop, not identify a variable suffix.

Further, the logic here seems to work, but doesn't seem very general or efficient. I imagine there is a better way to do this but I don't have time to play around with it at the moment - perhaps an update later.

In any case, I think the correct syntax most analogous to what you have tried is something like the following.

clear *

set more off
set obs 5
forvalues i = 1/84 {
    gen v`i' = runiform()
}


forvalues i =1/6 { 
    preserve
    local j = 6 + (`i'-1)*13
    local k = `j'+12
    if `j' == 6 {
        keep v1-v18
    }
    else if `j' > 6 & `j' < 71 {
        keep v1-v5 v`j'-v`k'
    }
    else keep v1-v5 v71-v84
    ds
    di
    restore 
}

I use ds here to simply list the variables in the data followed by di do display a blank line as a separator, but you could simply plug back in your export and it should work just fine.

Another thing to consider if you truly want temp data files is to consider using tempfile so that you aren't writing anything to disk. You might use

forvalues i = 1/6 {
    tempfile temp`i'
    // other commands
    save `temp`i''
}

This will create six Stata data files temp1 - temp6 that are held in memory until the program terminates.

Nick Cox
  • 35,529
  • 6
  • 31
  • 47
ander2ed
  • 1,318
  • 1
  • 11
  • 19
  • Thanks for your comments. For some reason, I thought STATA didnt have if block statements. I am glad to see that it does. The difference between qualifier and command is still a tricky one imo, but I get the general idea. I knew about commands just before or after brackets thing, but I couldnt get it to display right on this site. – DirkSa Jun 05 '16 at 13:49