How to rename a list of variables - variables

I generated a number of dummy variables from a variable indicating the the relevant quarter, labelled quarter, with the following command:
tabulate quarter, generate(timeq)
This generates a set of dummy variables that range from timeq1 to timeq68.
I am trying to think about a way to rename these variables to change the names in the following way
timeq1 into 1995q1
timeq2 into 1995q2
timeq3 into 1995q3
timeq4 into 1995q4
...
timeq68 into 2011q4

As has been pointed out, this question sorely lacks a good MCVE. but an answer is possible.
Note first that the ambition to create variable with names beginning with 1 and 2 is futile as it is a basic rule that such names are not legal. However, a beginning underscore is allowed.
The problem of renaming requires, I think, at least one loop. In fact, it seems easier to back up and create the variables from scratch.
The first part of the code just creates a sandbox for play.
clear
set obs 68
gen quarter = yq(1994, 4) + _n
format quarter %tq
The second part is ad hoc code for the problem. Note that variable labels can take the form desired.
forval y = 1995/2011 {
forval q = 1/4 {
gen _`y'q`q' = quarter == yq(`y', `q')
label var _`y'q`q' "`y'q`q'"
}
}

Related

Ampl syntax: return value at a specific position in set. AKA: use a set as an INDEX on another set

My question is this:
How can I use SUBSET (a discontinuous set) to refer to an index location in another set as opposed to an actual value? I see that ord() can be used to return the position of a value in a set, but I want the reverse of this...
my reason for needing this:
I have a model in which some of the set and data statements are roughly:
set ALL_TIME := {0..20000};
param DATA {ALL_TIME}; #read from file in later data statement;
set myTIME := {0...1000};
I am looping over the myTIME set and each time solving the model and then incrementing the start and end by 1: {1..1001}, {2..1002}, {3..1003}, etc.
I have another discontinuous set being read in from a file that looks something like this (yes below is bad syntax, the "...." is just there to mean that the pattern continues until it hits 1000 so I don't have to type it all) :
set SUBSET := {6,7,8,9,10, 16,17,18,19,20, 26,27.....}
Once myTIME increments such that it no longer contains "6", I get a subscript undefined error from a constraint which I understand to be because myTIME in this case is {7..1007} and thus in the following, tSUB=6 causes ALPHA[6] and is undefined:
subject to CONSTRAINT {tSUB in SUBSET}:
ALPHA [tSUB] = ALPHA[last(tSUB)];
What I want is to be able to use SUBSET to always refer to the same index location of ALPHA, DATA, etc.
So:
SUBSET[0] (which equals 6) should always be the 6th value of for example DATA:
{tSUB in SUBSET}: DATA[tSUB]. when tSUB is 0, I want the 6th value of DATA.
(I am new to Ampl and have a hard time wrapping my head around how indexing and sets work - if anything didn't make sense, please ask and I'll try to clarify. If you think it would be more helpful to see my actual code I'll try to sanitize the company data out and post it). Also, some of the code bits above have abysmal syntax. They are not copied from my code, just approximated to try to explain my problem. :)
You can get i-th member of set S with member(i, S), where i is a 1-based index and S is an ordered set. This is described in section 5.6 Ordered sets of the AMPL book.

How to display comparisons with set expression?

My dataset has WeekEndingDate and Sales. I am displaying a straight table with all the selected data but I need to have another table showing the following:
Sales (other columns...)
First week : 1,000
Last week : 1,350
Difference : 350
Difference %: 35%
My questions:
a) Can I have the above in one chart/table, or I need 4 different charts showing columns filtered by set expressions?
b) My strategy is having 2 variables (vMinWeek and vMaxWeek), and using them in set expressions. Is that the best route?
c) My set expressions (below) are not working - they sum the whole data set. Would you please help me understanding why?
=max ({$<WeekEndingDate={'$(vMinWeek)'}>} Sales)
Thank you for your help!
Mara
I think the reason your set isn't working is that your WeekEnd date is formatted as a date and your variable is formatted as a number.
The trick with Set Analysis is always to think what you would have to type in a list box to get to your answer. So even though QlikView stores WeekEnd 2014/08/18 as 41869 you can't type 41869 in the WeekEnd list box and get back that date. So I would make your variables of the form =date(min(WeekEnd)).
The second part of your question; getting the table you want. I would do like this. I make a loose table with the dimension values, dual is so that it sorts correctly in the chart we are going to build.
load dual(D,N) as DIM inline [
D,N
First Week,1
Last Week,2
Difference,3
Dif %,4
];
I like defining my variables in the script as well, so I would do this.
set vFirstWeek='=date(min(WeekEnd))';
set vLastWeek='=date(max(WeekEnd))';`
Then when building the straight table we use the dimension as DIM but because DIM isn't connected to anything we have to do some work to get it to display values that fit those dimension values. The num(,'# ##0') is just to format the % differently from the sums. For this to work the number format in the Number tab of the chart must be set to Expression Default.
if(DIM='First Week',num(sum({<WeekEnd={'$(vFirstWeek)'}>} Sales),'# ##0'),
if(DIM='Last Week',num(sum({<WeekEnd={'$(vLastWeek)'}>} Sales),'# ##0'),
if(DIM='Difference',num(sum({<WeekEnd={'$(vFirstWeek)'}>} Sales)-sum({<WeekEnd={'$(vLastWeek)'}>} Sales),'# ##0'),
if(DIM='Dif %',num((sum({<WeekEnd={'$(vFirstWeek)'}>} Sales)-sum({<WeekEnd={'$(vLastWeek)'}>} Sales))/sum({<WeekEnd={'$(vLastWeek)'}>} Sales),'0.00%')))))

Constructing a recursive compare with SQL

This is an ugly one. I wish I wasn't having to ask this question, but the project is already built such that we are handling heavy loads of validations in the database. Essentially, I'm trying to build a function that will take two stacks of data, weave them together with an unknown batch of operations or comparators, and produce a long string.
Yes, that was phrased very poorly, so I'm going to give an example. I have a form that can have multiple iterations of itself. For some reason, the system wants to know if the entered start date on any of these forms is equal to the entered end date on any of these forms. Unfortunately, due to the way the system is designed, everything is stored as a string, so I have to format it as a date first, before I can compare. Below is pseudo code, so please don't correct me on my syntax
Input data:
'logFormValidation("to_date(#) == to_date(^)"
, formname.control1name, formname.control2name)'
Now, as I mentioned, there are multiple iterations of this form, and I need to loop build a fully recursive comparison (note: it may not always be typical boolean comparisons, it could be internally called functions as well, so .In or anything like that won't work.) In the end, I need to get it into a format like below so the validation parser can read it.
OR(to_date(formname.control1name.1) == to_date(formname.control2name.1)
,to_date(formname.control1name.2) == to_date(formname.control2name.1)
,to_date(formname.control1name.3) == to_date(formname.control2name.1)
,to_date(formname.control1name.1) == to_date(formname.control2name.2)
:
:
,to_date(formname.control1name.n) == to_date(formname.control2name.n))
Yeah, it's ugly...but given the way our validation parser works, I don't have much of a choice. Any input on how this might be accomplished? I'm hoping for something more efficient than a double recursive loop, but don't have any ideas beyond that
Okay, seeing as my question is apparently terribly unclear, I'm going to add some more info. I don't know what comparison I will be performing on the items, I'm just trying to reformat the data into something useable for ANY given function. If I were to do this outside the database, it'd look something like this. Note: Pseudocode. '#' is the place marker in a function for vals1, '^' is a place marker for vals2.
function dynamicRecursiveValidation(string functionStr, strArray vals1, strArray vals2){
string finalFunction = "OR("
foreach(i in vals1){
foreach(j in vals2){
finalFunction += functionStr.replace('#', i).replace('^', j) + ",";
}
}
finalFunction.substring(0, finalFunction.length - 1); //to remove last comma
finalFunction += ")";
return finalFunction;
}
That is all I'm trying to accomplish. Take any given comparator and two arrays, and create a string that contains every possible combination. Given the substitution characters I listed above, below is a list of possible added operations
# > ^
to_date(#) == to_date(^)
someFunction(#, ^)
# * 2 - 3 <= ^ / 4
All I'm trying to do is produce the string that I will later execute, and I'm trying to do it without having to kill the server in a recursive loop
I don't have a solution code for this but you can algorithmically do the following
Create a temp table (start_date, end_date, formid) and populate it with every date from any existing form
Get the start_date from the form and simply:
SELECT end_date, form_id FROM temp_table WHERE end_date = <start date to check>
For the reverse
SELECT start_date, form_id FROM temp_table WHERE start_date = <end date to check>
If the database is available why not let it do all the heavy lifting.
I ended up performing a cross product of the data, and looping through the results. It wasn't the sort of solution I really wanted, but it worked.

How to comment on MATLAB variables

When I´m using MATLAB, sometimes I feel the need to make comments on some variables. I would like to save these comments inside these variables. So when I have to work with many variables in the workspace, and I forget the context of some of these variables I could read the comments I put in every one of them. So I would like to comment variables and keep the comments inside of them.
While I'm of the opinion that the best (and easiest) approach would be to make your variables self-documenting by giving them descriptive names, there is actually a way for you to do what you want using the object-oriented aspects of MATLAB. Specifically, you can create a new class which subclasses a built-in class so that it has an additional property describing the variable.
In fact, there is an example in the documentation that does exactly what you want. It creates a new class ExtendDouble that behaves just like a double except that it has a DataString property attached to it which describes the data in the variable. Using this subclass, you can do things like the following:
N = ExtendDouble(10,'The number of data points')
N =
The number of data points
10
and N could be used in expressions just as any double value would. Using this example subclass as a template, you could create "commented" versions of other built-in numeric classes, with the exception of those you are not allowed to subclass (char, cell, struct, and function_handle).
Of course, it should be noted that instead of using the ExtendDouble class like I did in the above example, I could instead define my variable like so:
nDataPoints = 10;
which makes the variable self-documenting, albeit with a little more typing needed. ;)
How about declaring another variable for your comments?
example:
\>> num = 5;
\>> numc = 'This is a number that contains 5';
\>> whos
...
This is my first post in StackOverflow. Thanks.
A convenient way to solve this is to have a function that does the storing and displaying of comments for you, i.e. something like the function below that will pop open a dialog box if you call it with comments('myVar') to allow you to enter new (or read/update previous) comments to variable (or function, or co-worker) labeled myVar.
Note that the comments will not be available in your next Matlab session. To make this happen, you have to add save/load functionality to comments (i.e. every time you change anything, you write to a file, and any time you start the function and database is empty, you load the file if possible).
function comments(name)
%COMMENTS stores comments for a matlab session
%
% comments(name) adds or updates a comment stored with the label "name"
%
% comments prints all the current comments
%# database is a n-by-2 cell array with {label, comment}
persistent database
%# check input and decide what to do
if nargin < 1 || isempty(name)
printDatabase;
else
updateDatabase;
end
function printDatabase
%# prints the database
if isempty(database)
fprintf('no comments stored yet\n')
else
for i=1:size(database,1)
fprintf('%20s : %s\n',database{i,1},database{i,2});
end
end
end
function updateDatabase
%# updates the database
%# check whether there is already a comment
if size(database,1) > 0 && any(strcmp(name,database(:,1)))
idx = strcmp(name,database(:,1));
comment = database(idx,2);
else
idx = size(database,1)+1;
comment = {''};
end
%# ask for new/updated comment
comment = inputdlg(sprintf('please enter comment for %s',name),'add comment',...
5,comment);
if ~isempty(comment)
database{idx,1} = name;
database(idx,2) = comment;
end
end
end
Always always always keep the Matlab editor open with a script documenting what you do. That is, variable assignments and calculations.
Only exceptions are very short sessions where you want to experiment. Once you have something -- add it to the file (It's also easier to cut and paste when you can see your entire history).
This way you can always start over. Just clear all and rerun the script. You never have random temporaries floating around in your workspace.
Eventually, when you are finished, you will also have something that is close to 'deliverable'.
Have you thought of using structures (or cells, although structures would require extra memory use)?
'>> dataset1.numerical=5;
'>> dataset1.comment='This is the dataset that contains 5';
dataset1 =
numerical: 5
comment: 'This is the dataset that contains 5'

Dynamically assigned table variables?

Writing a function in Lua, which creates two tables. I want the tables to be assigned to the value name with an x added, and one with a y added. For example if name was line, it would create two tables linex and liney, but I can't figure out how to do it. The following obviously doesn't work (and is just for display purposes) but how would I go about doing this?
function makelinep(x,y,minrand,maxrand,name,length)
name..x = {}
name..y = {}
Later I hope to access "linex" and "liney" after values have been written.
If you want these in the global name space you would use
_G[name..'x']={}
_G[name..'y']={}
For a module you'd use _M in place of _G.