Stata local based on other local - local

I am trying to use local with the value of an earlier use of local. An example: I want to define "final" and I want it to contain "var1 var2". However, I want to define "temp" first, and reuse its contents in the definition of final.
Here is what I tried:
local temp "var2"
local final "var1 " `temp'
Can anyone tell me what I am doing wrong?

An example that works:
// example data
sysuse auto, clear
// what you want
local first weight
local second `first' mpg
// example use of local second
regress price `second'
Edit
To answer your comment:
Yes, your problem are the double quotes. That doesn't mean, however, that using double quotes will automatically get you in trouble. For example, this will work:
// example data
sysuse auto, clear
// what you want
local first "weight"
local second "mpg `first'"
// example use of local second
regress price `second'
Double quotes here are interpreted as string delimiters, and so will be stripped. When local first is (de)referenced in local second "mpg `first'", macro-substitution will insert weight, not "weight". Afterwards, when local second is (de)referenced in regress ..., macro-substitution results in mpg weight, not "mpg weight". So it's all legal syntax.
Your example contains invalid syntax. You delimit the first piece with double quotes and then continue with another piece:
`temp'
That is considered illegal.
Stata doesn't mind if we omit the double quotes in the local statement, which is why my first example works. See [U] 18.3.4 Macros and expressions.
See also http://www.stata.com/statalist/archive/2009-01/msg00282.html and help quotes.

Related

Finding strings between two strings in lua

I have been trying to find all possible strings in between 2 strings
This is my input: "print/// to be able to put any amount of strings here endprint///"
The goal is to print every string in between print/// and endprint///
You can use Lua's string patterns to achieve that.
local text = "print/// to be able to put any amount of strings here endprint///"
print(text:match("print///(.*)endprint///"))
The pattern "print///(.*)endprint///" captures any character that is between "print///" and "endprint///"
Lua string patterns here
In this kind of problem, you don't use the greedy quantifiers * or +, instead, you use the lazy quantifier -. This is because * matches until the last occurrence of the sub-pattern after it, while - matches until the first occurence of the sub-pattern after it. So, you should use this pattern:
print///(.-)endprint///
And to match it in Lua, you do this:
local text = "print/// to be able to put any amount of strings here endprint///"
local match = text:match("print///(.-)endprint///")
-- `match` should now be the text in-between.
print(match) -- "to be able to put any amount of strings here "

Systematically renaming variables in SPSS (without Python)

I'm looking for a solution to rename variables in SPSS. I can't use Python because of software restrictions at my workplace.
The goal is to rename variables into "oldname_new".
I tried "do repeat" like this, but it can't be combined with the rename function.
do repeat x= var1 to var100.
rename var (x=concat("x","_new")).
end repeat print.
exe.
Also, I figured that even without the do repeat, the rename command doesn't allow concat and similar commands? Is that correct?
So, is there any solution for this in SPSS?
As you found out you can't use rename within a do repeat loop.
SPSS macro can do this -
define DoNewnames ()
rename vars
!do !v=1 !to 100 !concat("var", !v, " = var", !v, "_new") !doend .
!enddefine.
* now the macro is defined, we can run it.
DoNewnames .
EDIT:
The code above is good for a set of variables with systematic names. In case the names are not systematic, you will need a different macro:
define DoNewnames (varlist=!cmdend)
rename vars
!do !v !in(!varlist) !concat(!v, " = ", !v, "_new") !doend .
!enddefine.
* Now in this case you need to feed the variable list into the macro.
DoNewnames varlist = age sex thisvar thatvar othervar.
If you want to see the syntax generated by the macro (like you did with end repeat print) you can run this before running the macro:
set mprint on.
EDIT 2:
As the OP says - the last macro requires naming all the variables to be renamed, which is a hassle if there are many. So the next code will get them all automatically without naming them individually. The process - as described in #petit_dejeuner's comment - creates a new data set that contains each original variable as an observation, and the original variable name as a value (=meta information about the variables, like a codebook). This way, you can recode the variable name into the renaming syntax.
dataset name orig.
DATASET DECLARE varnames.
OMS /SELECT TABLES /IF COMMANDS=['File Information'] SUBTYPES=['Variable Information']
/DESTINATION FORMAT=SAV OUTFILE='varnames' VIEWER=NO.
display dictionary.
omsend.
dataset activate varnames.
string cmd (a50).
compute cmd=concat("rename vars ", rtrim(var1), " = ", rtrim(var1), "_new .").
* Before creating the rename syntax in the following line, this is your chance to remove variables from the list which you do not wish to rename (using "select if" etc' on VAR1).
write out="my rename syntax.sps" /cmd.
dataset activate orig.
insert file="my rename syntax.sps" .
A couple of notes:
Before writing to (and inserting from) "my rename syntax.sps" you may need to add a writable path in the file name.
This code will rename ALL the variable in the dataset. If you want to avoid some of the variables - you should filter them in the variable list before writing out to "my rename syntax.sps" (see where I point this out in the code).

How to reverse the words in the string in automation anywhere

I am trying to reverse the string For Example string s= "Hello Robot Process Automation" will be changed to String s="Automation Process Robot Hello" in automation anywhere.
I tried below steps:-
Reverse the sentence(it reverses the words and alphabets in words as well).
2.Split the sentence and put into list variable
used loop and in same loop i reversed again the alphabets so now the sentence will be like "Automation" "Process" "Robot" "Hello" into one list
4 I am not getting next step after this(joining of these words).
Please help.
For reversing the string as per above requirement, below are the steps:
Create a variable for storing the reversed string called vReversedString
Reverse the given string i.e from above string the output should be noitamotuA ssecorP toboR olleH
Split the reversed string by space deliminator and store in my-list-variable
Loop through my-list-variable
Reverse the each element through the loop. For example, In this case the first element is noitamotuA by reversing this you'll be getting Automation as an output, store it to system variable clipboard or create a new variable to hold each element.
Concatenate and store to vReversedString = $vReversedString$ $clipboard$

SPSS save decimal number to ASCII

I am trying to save a numeric-with-decimal-places(f8.6) variable from an SPSS file into a fixed ASCII file. The goal is to write it into certain columns of the ASCII (21 to 30).
WRITE OUTFILE='C:\misc\ascii.dat'
ENCODING='UTF8'
TABLE /1
variable 21-30.
exe.
writes to the correct positions, but not with decimals.
variable 21-30 (f)
does the same thing.
variable (f8.6)
saves with decimals, but on positions 1 to 10.
variable 21-30 (f8.6)
results in an error, because apparently you cannot specify both columns and format.
I know two workarounds, but both involve additional data editing, which I'd rather not do:
Convert variable to string and save it as string - but I am not sure about the implications (encoding, decimal places, or whatever other thing I am not even considering)
add an empty string variable with length of 20 before my variable.
But is there a straightforward way of doing this, without workarounds ?
You can add the 20 spaces in the command itself, like this:
WRITE OUTFILE='C:\misc\ascii.dat'
ENCODING='UTF8'
TABLE / ' ' YourNumVar (f8.6) .
exe.

TeX edef macro blues

I spent some time trying to write a 'helper' macro to test a parameter for a new value, else use the existing value -- default values exist for all parameter positions.
I wanted to be able to write:
\foo{left}{nil}{}{20pt}
so that the second parameter would used its current value but the third value would be the value empty string. I wanted to use the notation:
\edef\pA{\isnil{#1}{\pA){#1}} % one for each parameter
I defined \isnil like so:
\def\nil{nil}
\def\isnil#1#2#3{%
\edef\nilTest{#1}%
\ifx\nilTest\nil#2\else#3\fi
}
but when I tried to run it, TeX complained that \nilTest is an undefined control sequence.
That is true of course, but I want \pA to hold a value, not a recipe for a value, so it must be an \edef which means that all the macro test will be expanded but while will the \edef not protect the \nilTest -- is this a place to use \noexpand -- that did not seem to work for me.
EDIT: no digits in \cs names (yeah, I knew that.)
Why doesn't your solution work? \edef\pA{\isnil{#1}{\pA){#1}} expands \isnil and gets \edef\nilTest{.... Now \edef is not expandable and falls into a sequence of \pA as the first element. An attempt to expand the next macro \nilTest fails.
Use \setpar from the following code to change your parameter.
\def\nil{nil}
\def\setpar#1#2{%
\edef\nilTest{#2}%
\ifx\nilTest\nil\else\let#1\nilTest\fi}
\def\first{old first}
\def\second{old second}
\setpar \first{nil}
\setpar \second{new}
first = ``\first'', second = ``\second''
P.S. Do not use digits in your macro.

Resources