Extract value label in command [stata] - label

I am trying to create a new string variable that combines the string of a real number (an ID) with a name. The name is a numeric variable with a value label.
Example data can be found below:
* Input Data
clear
input long num id
1 689347
2 972623
end
label values num num
label def num 1 "Label A" 2 "Label B"
+------------------+
| num id |
|------------------|
| Label A 689347 |
| Label B 972623 |
+------------------+
What I would like to do is create a string of the type 689347 - Label A. This is very easy to do by simply using decode on num, then writing a new string as follows:
tempvar numstr
decode num, gen(`numstr')
gen label = string(id) + " - " + `numstr'
+-------------------------------------+
| num id label |
|-------------------------------------|
| Label A 689347 689347 - Label A |
| Label B 972623 972623 - Label B |
+-------------------------------------+
This is already pretty easy, but is there a way to do this in one line, without the decode command?
For example something like:
gen label = string(if) + " " + string(num)
The problem with this is, of course, that this will just give a string of the real number value (1 and 2) that num takes on.
In this post you can see how to reference the value label in an if command.
My question is:
Is there a way to tell Stata to create a string and pull the value label instead of the value?

The best I can do is two lines.
decode num, generate(label)
replace label = string(id) + " - " + label

If you do not want to use decode, then this does the trick:
generate label = ""
forvalues i = 1 / 2 {
replace label = string(id) + " - " + "`: label num `i''" in `i'
}

Related

Syntax to generate a Syntax in SPSS

I’m trying to construct a Syntax to generate a Syntax in SPSS, but I’m having some issues…
I have an excel file with metadata and I would like to use it in order to make a syntax to extract information from it (like this, if I have a huge database, I just need to keep the excel updated – add/delete variables, etc. - and then run a syntax to extract the needed information for a new syntax).
I also noticed the produced syntax has always around 15Mb, which is a lot (applied to more than 500 lines)!
I don’t use Python due to run syntax in different computers and/or configurations.
Any ideas? Can anyone please help me?
Thank you in advance.
Example:
(test.xlsx – sheet 1)
Var Code Label List Var_label (concatenate Var+Label)
V1 3 Sex 1 V1 “Sex”
V2 1 Work 2 V2 “Work”
V3 3 Country 3 V3 “Country”
V4 1 Married 2 V4 “Married”
V5 1 Kids 2 V5 “Kids”
V6 2 Satisf1 4 V6 “Satisf1”
V7 2 Satisf2 4 V7 “Satisf2”
(information from other file)
List = 1
1 “Male”
2 “Female”
List = 2
1 “Yes”
2 “No”
List = 3
1 “Europe”
2 “America”
3 “Asia”
4 “Africa”
5 “Oceania”
List = 4
1 “Very unsatisfied”
10 “Very satisfied”
I want to make a Syntax that generates a new syntax to apply “VARIABLE LABELS” and “VALUE LABELS”. So, I thought about something like this:
GET DATA
/TYPE=XLSX
/FILE="test.xlsx"
/SHEET=name 'sheet 1'
/CELLRANGE=FULL
/READNAMES=ON
/DATATYPEMIN PERCENTAGE=95.0.
EXECUTE.
STRING vlb (A15) labels (A150) value (A12) lab (A1500) point (A2) separate (A50) space (A2) list1 (A100) list2 (A100).
SELECT IF (Code=1).
COMPUTE vlb = "VARIABLE LABELS".
COMPUTE labels = CONCAT (RTRIM(Var_label)," ").
COMPUTE point = ".".
COMPUTE value = "VALUE LABELS".
COMPUTE lab = CONCAT (RTRIM(Var)," ").
COMPUTE list1 = '1 " Yes "'.
COMPUTE list2 = '2 "No".'.
COMPUTE space = " ".
COMPUTE separate="************************************************.".
WRITE OUTFILE = "list_01.sps" / vlb.
WRITE OUTFILE = "list_01.sps" /labels.
WRITE OUTFILE = "list_01.sps" /point.
WRITE OUTFILE = "list_01.sps" /value.
WRITE OUTFILE = "list_01.sps" /lab.
WRITE OUTFILE = "list_01.sps" /list1.
WRITE OUTFILE = "list_01.sps" /list2.
WRITE OUTFILE = "list_01.sps" /space.
WRITE OUTFILE = "list_01.sps" /separate.
WRITE OUTFILE = "list_01.sps" /space.
If there is only one variable with same list (ex: V1), it works ok. However, if there is more than one variable having the same list, it reproduces the codes as much times as number of variables (Ex: V2, V4 and V5).
What I have (Ex: V2, V4 and V5), after running code above:
VARIABLE LABELS
V2 "Work"
.
VALUE LABELS
V2
1 " Yes "
2 " No "
************************************************.
VARIABLE LABELS
V4 "Married"
.
VALUE LABELS
V4
1 " Yes "
2 " No "
************************************************.
VARIABLE LABELS
V5 "Kids"
.
VALUE LABELS
V5
1 " Yes "
2 " No "
************************************************.
What I would like to have:
VARIABLE LABELS
V2 "Work"
V4 "Married"
V5 "Kids"
.
VALUE LABELS
V2 V4 V5
1 " Yes "
2 " No "
I think there are probably ways to automate the whole process better, including the use of your second data source. But for the scope of this question I will suggest a way to get what you asked for specifically.
The key is to build the command with special conditions for first and last lines:
string cmd1 cmd2 (a200).
sort cases by code.
match files /file=* /first=first /last=last /by code. /* marking first and last lines.
do if first.
compute cmd1="VARIABLE LABELS".
compute cmd2="VALUE LABELS".
end if.
if not first cmd1=concat(rtrim(cmd1), " /"). /* "/" only appears from the second varname.
compute cmd1=concat(rtrim(cmd1), " ", Var_label).
compute cmd2=concat(rtrim(cmd2), " ", Var).
do if last.
compute cmd1=concat(rtrim(cmd1), " .").
compute cmd2=concat(rtrim(cmd2), " ", ' 1 " Yes " 2 "No". ').
end if.
exe.
The commands are now ready, but we don't want to get them mixed up so we'll stack them one under the other, and only then write them out:
add files /file=* /rename cmd1=cmd /file=* /rename cmd2=cmd.
exe.
WRITE OUTFILE = "var definitions.sps" / cmd .
exe.
EDIT:
Note that the code above assumes you've already run a select cases if code = ... and that there is a single code in all the remaining lines.
Note also I added an exe. command at the end - without running that the new syntax will appear empty.

DOORS Compound Filter Dilemma

DOORS Version: 9.5.2.1
I'll try to break this down as simple as I can. First, I'll start with the data. Assume I have a module, Module, in DOORS. Module is comprised of:
Tree Structure
Assume that Object Text for headings and sub-headings are blank, and assume Object Text for the remaining Level 3 objects is the same as the name of the object itself. For example, Object Heading is blank for Object_1.1.0-1, but its Object Text is "Object_1.1.0-1".
- Module
- 1 Heading1 // Object Heading: "Heading1" ; Object Number: 1
| - 1.1 Sub-Heading1.1 // Object Heading: "Sub-Heading1.1" ; Object Number: 1.1
| | + Object_1.1.0-1 // Object Heading: "" ; Object Number: 1.1.0-1
| | + Object_1.1.0-2 // Object Heading: "" ; Object Number: 1.1.0-2
| | | .
| | | .
| | | .
| | + Object_1.1.0-A // Object Heading: "" ; Object Number: 1.1.0-A
| |
| - 1.2 Sub-Heading1.2 // Object Heading: "Sub-Heading1.2" ; Object Number: 1.2
| + Object_1.2.0-1 // Object Heading: "" ; Object Number: 1.2.0-1
| + Object_1.2.0-2 // Object Heading: "" ; Object Number: 1.2.0-2
| | .
| | .
| | .
| + Object_1.2.0-B // Object Heading: "" ; Object Number: 1.2.0-B
|
- 2 Heading2 // Object Heading: "Heading2" ; Object Number: 2
- 2.1 Sub-Heading2.1 // Object Heading: "Sub-Heading2.1" ; Object Number: 2.1
| + Object_2.1.0-1 // Object Heading: "" ; Object Number: 2.1.0-1
| + Object_2.1.0-2 // Object Heading: "" ; Object Number: 2.1.0-2
| | .
| | .
| | .
| + Object_2.1.0-C // Object Heading: "" ; Object Number: 2.1.0-C
|
- 2.2 Sub-Heading2.1 // Object Heading: "Sub-Heading2.1" ; Object Number 2.2
+ Object_2.2.0-1 // Object Heading: "" ; Object Number: 2.2.0-1
+ Object_2.2.0-2 // Object Heading: "" ; Object Number: 2.2.0-2
| .
| .
| .
+ Object_2.2.0-D // Object Heading: "" ; Object Number: 2.2.0-D
And so on and so forth . . .
Attributes
*Object Heading and Text*, Version, Data
Object Heading and Text seems to be a DOORS thing, so I won't explain that here. Data here is generic (and, in reality, represents more than one attribute). Some data is applicable to some versions while other data is applicable to other versions. The data for different versions may intersect while some data for other versions are mutually exclusive. Version is a single string that delimits the different versions by new lines, "\n". So, let's assume that Version is:
v1\nv2\nv3 . . . v\nvX
or, in a more readable format:
v1
v2
v3
.
.
.
vX
What's more, Version for one object may be (comma-separated here for readability) v1, v2, v3, . . ., vX while for another it might be v1, v3 and for another perhaps just v2. Any combination of available versions, really.
The Problem
What I'm attempting to do seems to me like it should be easy. A no-brainer. Just to pick an example, let's say I want to apply a filter whereby I view only Sub-Heading1.2 and its children, and that only for Version v3. I've tried many variations on the theme, but I can only seem to accomplish one or the other. Either I successfully isolate data for a single section or a single version, but I cannot get both. When I apply a filter for a single section, say Sub-Heading1.2 and its children, and then AND that with "includes v3"; I will get that section, but it refuses to show only that section only for v3.
In any programming language, a and b and c evaluates to true IF AND ONLY IF a and b and c. What I'm seeing in DOORS seems to me to be more like (a and b) or c.
With a DOORS database described as above, how can I view only the objects in a given range (or an object and its descendants) only for a given version? I know DXL exists as a potential solution, but a GUI solution is preferable.
Your issue is Include Descendants. This options specifically ignores the filter. What it is really saying is, "Show me everything that matches my filter, and all of their descendants".
Using your example above, what you want for a filter is:
Object Number >= 1.2
and
Object Number < 2 (or maybe 1.3 depending on how you want it)
and
Version includes v3
This will give you what you are looking for. Be sure NOT to Include Descendants as this will negate the second rule in the filter.
Good luck!

Ruby CSV re-arranging Array

I'm not sure what the appropriate title for this question so if someone could help me with that also, it would be nice.
-
I have a CSV file that looks something like
ID | Num
a | 1
a | 2
a | 3
b | 4
b | 5
c | 6
c | 7
I need the result to be:
ID | Num
a | 1,2,3,4
b | 4,5
c | 6,7
Currently, my solution is:
ary = CSV.open('some_file')
final = Array.new
id = ary[1][0] # ary[0] is "id"
numJoin = ary[1][1]
(1..ary.length).each do |i|
if id == ary[i+1][0]
numJoin = numJoin + "," + ary[i+1][1]
else
final << [id,numJoin]
id = ary[i+1][0]
numJoin = ary[i+1]]1]
end
end
It works, but I would like to have the opportunity to learn other ways to solve this, as I think there should be simpler ways to do this..
Thanks in advance.
You can use group_by, which groups by the return value of the block passed to it, in this case, it's the ID.
ary = ary.group_by { |v| v[0] }
P.S That file ain't looking like a CSV.

PySide: Formatted text in QComboBox

I have this snippet of code:
import PySide.QtGui
app = PySide.QtGui.QApplication('')
wnd = PySide.QtGui.QWidget()
mly = PySide.QtGui.QVBoxLayout()
combo = PySide.QtGui.QComboBox()
table = [ ('Lorem','ipsum','dolor','sit','amet'),
('Aliquam','sodales','nunc','eget','lorem'),
('Vivamus','et','sapien','mattis','vulputate'),
('Integer','ac','dolor','commodo','cursus'),
('Sed','sed','erat','non','magna'),
('Duis','vestibulum','eu','tortor','euismod') ]
combo.clear()
for (one,two,three,four,five) in table:
combo.addItem('%-12s | %-12s | %-12s | %-12s | %-12s' % (one,two,three,four,five))
mly.addWidget(combo)
mly.addStretch(1)
wnd.setLayout(mly)
wnd.show()
app.exec_()
I have obtained this (1) and I'm looking for something like (2): all columns tabulated.
The combobox have the standard proportional font (MS Shell Dlg 2 from QtDesigner). I don't want to use monospaced font.
I have tried to calculate the maximum width in pixels of every column with combo.fontMetrics().boundingRect(text).width() and fill every column with spaces:
borde = ' '
unspc = ' '
maxwdt = {0:0, 1:0, 2:0, 3:0, 4:0}
for lstlin in table:
for (ndx,val) in enumerate(lstlin):
unwdt = combo.fontMetrics().boundingRect(borde + val + borde).width()
if (unwdt > maxwdt[ndx]):
maxwdt[ndx] = unwdt
combo.clear()
for lstlin in table:
txtlin = ''
for (ndx,val) in enumerate(lstlin):
txtcmp = borde + val + borde
while (combo.fontMetrics().boundingRect(txtcmp).width() < maxwdt[ndx]):
txtcmp += unspc
txtlin += txtcmp + '|'
combo.addItem(txtlin)
and I have obtained (3).
There are any other method to format a text with proportional font for use in a QComboBox?. Thanks.
Your algorithm is fine, but it can only be as accurate as the width of a standard space in the proportional font you are using.
To get more accurate results, use the thinnest possible whitespace character available. For fonts with good unicode support, this will be the HAIR SPACE U+200A.
On Linux (using the DejaVu Sans font) I can exactly reproduce (3) by changing the following two lines in your example script:
# hair-space
unspc = '\u200a'
borde = unspc * 10

WebFocus, two title columns and merging cells

If i have a table in a WebFocus Raport design
+--------+---------+--------+---------+
| left_1 | right_1 | left_2 | right_2 |
+--------+---------+--------+---------+
| v11 | p11 | v21 | v21 |
+--------+---------+--------+---------+
| v12 | p12 | v22 | v22 |
....
How to do a such table with syllabus column titles:
+-------+-------+-------+-------+
| One | Two |
+-------+-------+-------+-------+
| left | right | left | right |
+-------+-------+-------+-------+
| v11 | p11 | v21 | v21 |
+-------+-------+-------+-------+
| v12 | p12 | v22 | v22 |
....
Thank you
Sorry for the delay of the answer :)
To rename columns, with the AS command. Example:
TABLE FILE SYSTABLE
PRINT NAME
COMPUTE LEFT1/A3 = 'v11'; AS 'left';
COMPUTE RIGHT1/A3 = 'p11'; AS 'right';
COMPUTE LEFT2/A3 = 'v21'; AS 'left';
COMPUTE RIGHT2/A3 = 'p21'; AS 'right';
IF RECORDLIMIT EQ 10
END
To put the heading columns, you can work with the ACROSS command but it will be more tricky that if u use simply SUBHEAD. With the same example:
TABLE FILE SYSTABLE
PRINT NAME NOPRINT
COMPUTE LEFT1/A3 = 'v11'; AS 'left';
COMPUTE RIGHT1/A3 = 'p11'; AS 'right';
COMPUTE LEFT2/A3 = 'v21'; AS 'left';
COMPUTE RIGHT2/A3 = 'p21'; AS 'right';
IF RECORDLIMIT EQ 10
ON TABLE SUBHEAD
"<+0>One<+0> Two"
ON TABLE PCHOLD FORMAT HTML
ON TABLE SET HTMLCSS ON
ON TABLE SET STYLE *
UNITS=IN, PAGESIZE='Letter',
LEFTMARGIN=0.500000, RIGHTMARGIN=0.500000,
TOPMARGIN=0.500000, BOTTOMMARGIN=0.500000,
SQUEEZE=ON, GRID=OFF, ORIENTATION=LANDSCAPE, $
TYPE=REPORT,FONT='ARIAL',SIZE=9,$
TYPE=TABHEADING,HEADALIGN=BODY,$
TYPE=TABHEADING, LINE=1, ITEM=1, COLSPAN=2, SQUEEZE=ON,$
TYPE=TABHEADING, LINE=1, ITEM=2, COLSPAN=2, SQUEEZE=ON,$
ENDSTYLE
END
Hope it helps!
I'm not entirely sure if you load the headers as a field or if that is the field name
But this might help you
Define fields
TITL1/A3 = 'One';
TITL2/A3 = 'Two';
BLANK/A1 = '';
Edit the Left and Right title fields to remove the _1 or _2
Print the fields BY BLANK NOPRINT
Add
ON BLANK SUBHEAD
"
You can also add more rows to the subhead if you need more titles
You can easily do it by embedding HTML/CSS scripts in report(.fex) file.
just add the HTML/css code at the end of the file.
For eg.
-HTMLFORM BEGIN // to start styling your generated report table with HTML/CSS
TABLE tr
td:first-child // applies on 1st row ONLY.It can be td or th.
{
colspan = "2"; //to merge 2 columns
}
-HTMLFORM END //end HTML.
So the first row must have two cells having title "ONE" and "TWO"(in your case), and both cells must have property of colspan = "2"
Also you can refer:
Colspan propery from here
manipulating first row of table from here
Second option is to write the whole code in a file and save it in .htm/.html format and just insert the file in to WEBFOCUS(.fex) file.For eg.
-HTMLFORM BEGIN
-INCLUDE HTML_FILE.HTML
-HTMLFORM END
Hope it helps.Thanks.

Resources