I have an excel file with information about variables (excel1) and another one with information about lists (excel2).
In order to create a syntax to generate a new syntax to create VARIABLE and VALUES LABELS, I used solution proposed by #eli.k here.
But with this solution I have to have a dataset with lists so I could use it instead of writing it “by hand” (copy/paste) (here). One problem came with L2, which has 195 entries so the new create variable would need to be bigger that 20.000 characters (is this possible in SPSS?), appearing all in one line.
What I want to know is if it’s possible to use excel2 automatically in code, line by line.
Using the following code:
GET DATA
/TYPE=XLSX
/FILE=" D:\excel1.xlsx "
/SHEET=name 'Folha1'
/CELLRANGE=FULL
/READNAMES=ON
/DATATYPEMIN PERCENTAGE=95.0.
STRING cmd1 cmd2 (a200).
SORT CASES by List.
MATCH FILES /FILE=* /FIRST=first /LAST=last /BY List. /* 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 "Afghanistan" 2 "Albania" (…) 195 "Zimbabwe".').
END IF.
EXECUTE.
SELECT IF ('List' 'L2').
ADD FILES /file=* /rename cmd1=cmd /file=* /rename cmd2=cmd.
EXECUTE.
I would like to know if there is a way to replace ' 1 "Afghanistan" 2 "Albania" (…) 195 "Zimbabwe".'' by some function/procedure to grab information from excel2 concerning L2, and showing it line by line:
(…)
VARIABLE LABELS V2 "Country"
/ V3 "Country Mother"
/ V4 "Country Father".
VALUE LABELS V2
V3
V4
1 "Afghanistan"
2 "Albania"
(…)
195 "Zimbabwe".
Thanks for helping me!
This issue is pretty complex and would usually be beyond the scope of Stack-Overflow Q&A but here's my answer anyway:
First I recreate the parts of your example data concerning the value labels only:
data list list/var list (2a5).
begin data
"v1" "L1"
"v2" "L2"
"v3" "L2"
"v4" "L2"
end data.
dataset name xl1.
data list list/list (a5) nb (f5) nb_txt (a20).
begin data
"L1" 1 "Female"
"L1" 2 "Male"
"L2" 1 "Afghanistan"
"L2" 2 "Albania"
"L2" 43 "Israel"
"L2" 195 "Zimbabwe"
end data.
dataset name xl2.
data list list/v1 v2 v3 v4 (4f3).
begin data
1 1 2 3
2 2 2 43
1 2 1 195
end data.
dataset name gen.
Now to work:
The first part is to create a macro for each list of variable labels. since some of the lists are long, I use ADD Value labels separately for each value.
dataset activate xl2.
string cmd (a200) cmdFin (a20).
sort cases by list nb.
match files /file=* /by list /first=first /last=last.
compute cmd=concat("add value labels !1 ", string(nb,f6), " '", rtrim(nb_txt), "' .").
if first cmd=concat("define dolist_", list, " (!pos=!cmdend) ", rtrim(cmd)).
if last cmdFin=" !enddefine .".
write outfile="path\create value label macros.sps"/cmd/cmdfin.
exe.
insert file="path\create value label macros.sps".
After inserting the generated syntax a macro has been defined for each of the value lists. Now we create an additional syntax that will run the related macro for each of the variable names in the list:
dataset activate xl1.
string cmd (a200).
compute cmd=concat("dolist_", list, " ", var, " .").
write outfile="path\run value label macros.sps"/cmd.
exe.
Now we can actually try out the generated macros on our original data:
dataset activate gen.
insert file="path\run value label macros.sps".
Related
I am trying to build a string of values to be inserted into an SQL IN list. For example -
SELECT * FROM TABLE WHERE field IN ('AAA', 'BBB', 'CCC', 'DDD')
The list that I want needs to be constructed from values within a single column of my dataset but I'm struggling to find a way to concatenate those values.
My first thought was to use CASESTOVARS to put each of the values into columns prior to concat. This is simple but the number of cases is variable.
Is there a way to concat all fields without specifying?
Or is there a better way to go about this?
Unfortunately Python is not an option for me in this instance.
A simple sample dataset would be -
CasestoConcat
AAA
BBB
CCC
DDD
You can use the lag function for this.
First creating a bit of sample data to demonstrate on:
data list free/grp (F1) txt (a5).
begin data
1 "aaa" 1 "bb" 1 "cccc" 2 "d" 2 "ee" 2 "fff" 2 "ggggg" 3 "hh" 3 "iii"
end data.
Now the following code makes sure that rows that belong together are consecutive. You can also sort by any other relevant variable to keep the combined text in a specific order.
sort cases by grp.
string merged (A1000).
compute merged=txt.
if $casenum>1 and grp=lag(grp) merged=concat(rtrim(merged), " ", rtrim(lag(merged))).
exe.
At this point if you want to just keep the line that has all the concatenated texts, you can use this:
add files /file=* /by grp /last=lst.
select if lst=1.
exe.
This error occurs on line 3 of my code and I don't know why.
I'm trying to create multiple variables with x..q, but it doesn't work.
for i=1,3 do
for q=1,3 do
x..q=i+1
print(x..q)
end
end
The output should be:
2
2
2
3
3
3
4
4
4
But instead it returns the error in the title.
If you want to create multiple global variables, use code like this:
for i=1,3 do
for q=1,3 do
_G["x"..q]=i+1
print(_G["x"..q])
end
end
This code will create globals x1, x2, and x3.
But I think you'd be better off using a table:
x={}
for i=1,3 do
for q=1,3 do
x[q]=i+1
print(x[q])
end
end
I believe you are using the operator .. unintentionally.
When accessing a value of a table, the syntax is x.q. Programming in Lua: 2.5 – Tables
To represent records, you use the field name as an index. Lua supports this representation by providing a.name as syntactic sugar for a["name"]. So, we could write the last lines of the previous example in a cleanlier manner as
a.x = 10 -- same as a["x"] = 10
print(a.x) -- same as print(a["x"])
print(a.y) -- same as print(a["y"])
When concatenating a string the syntax is x .. q.
Programming in Lua: 3.4 – Concatenation
Lua denotes the string concatenation operator by ".." (two dots). If any of its operands is a number, Lua converts that number to a string.
print("Hello " .. "World") --> Hello World
print(0 .. 1) --> 01
I am stuck trying to figure out how to read the strings from a textgrid which is open in the window but not saved to the hard disk as a raw text file. My goal is to manipulate the strings and save them later.
I want to do something like this but don't really understand how the syntax would work.
tG$ = selectObject: selected$("TextGrid")
stringID = Read Strings from tG
numberOfStrings = Get number of strings
for stringNumber from 0 to numberOfStrings
selectObject: stringID
line$ = Get string: stringNumber
...
You need to loop through the intervals in the TextGrid and use appendFileLine to output the labels to a text file. For example:
# Your need to select the TextGrid manually, and it has only one tier (tier number 1)
outputFile$ = "~/Desktop/output.txt"
writeFile: outputFile$, "" ; start from an empty .txt
numberOfIntervals = Get number of intervals: 1 ; (this is tier 1)
for interval to numberOfIntervals
label$ = Get label of interval: 1, interval
if label$ != "" ; (we just want non-empty intervals)
xmin = Get start time of interval: 1, interval
xmax = Get end time of interval: 1, interval
appendFileLine: outputFile$, "'label$''tab$''xmin''tab$''xmax'"
endif
endfor
This script will output a .txt file with tab delimited values: label, xmin, xmax. You can change the appendFileLine arguments to your needs (tab$ is a predefined variable, which is... a tab).
TextGrid labels are not directly translatable to a Strings object because, unlike a TextGrid, Strings objects do not have tiers. So you could have code that takes all of the labels of a specific tier in a TextGrid and pushes them into a Strings object.
0. Creating an empty Strings
The problem here is that Praat does not want you to populate Strings object yourself, so there is no Create empty Strings.... However, you can subvert one of the existing commands to do this:
Create Strings as tokens: ""
1. Pushing the labels to a Strings object
Now that we have an empty Strings to populate, we can get to work:
procedure labelsToStrings: .tier
.textgrid = selected("TextGrid")
# Make sure this works with interval and point tiers
.item$ = if do("Is interval tier...", .tier) then
... "interval" else "point" fi
# Make the empty Strings
.strings = Create Strings as tokens: ""
Rename: selected$("TextGrid")
# Fetch each label, and insert it to the Strings object
selectObject: .textgrid
.n = do("Get number of " + .item$ + "s...", .tier)
for .i to .n
selectObject: .textgrid
.label$ = do$("Get label of " + .item$ + "...", .tier, .i)
# I assume you don't care about empty labels?
if .label$ != ""
selectObject: .strings
Insert string: 0, .label$
endif
endfor
# Make sure the new object is selected
selectObject: .strings
endproc
2. Profit!
You can try it out:
synth = Create SpeechSynthesizer: "English", "default"
To Sound: "This is some text.", "yes"
sound = selected("Sound")
textgrid = selected("TextGrid")
selectObject: textgrid
#labelsToStrings: 4
removeObject: sound, synth
View & Edit
3. Bonus
If you are interested in getting all the labels in a more manageable package, you might also be interested in the Index specified labels... command from the tgutils plugin, which I also wrote. (I know: I'm amazing at naming things).
That one does something similar to this, but instead of using a Strings object, it dumps all the labels to a Table, as well as the timestamp of points, or the start and end of intervals. And you can also specify subsets of labels to consider using a literal match or a regular expression.
With it, you can re-write #labelsToStrings to look like this:
procedure labelsToStrings: .tier
.name$ = selected$("TextGrid")
runScript: preferencesDirectory$ + "/plugin_tgutils/scripts/" +
... "index_specified_labels.praat", .tier, ".+", "yes"
.table = selected("Table")
Create Strings as tokens: ""
Rename: .name$
for .i to Object_'.table'.nrow
.label$ = Object_'.table'$[.i, "label"]
Insert string: 0, .label$
endfor
removeObject: .table
endproc
I want to put letters instead of numbers.For example, if I have the following statement:
{for $node=1 to {$nr_nods}}
{$nod}<br>
{/for}
where {$nr_nods}=3, will show
1
2
3
,but Y want display
A
B
C
how make this?
In php, assign an array to the template with the equivalences:
$smarty->assign('nums'=>array(1=>'A',2=>'B',3=>'C'));
and then just output the values by key:
{$nums.$nod}
I researched delimit issue for a while and I pull useful codes here and there, but I can't quite put it together.
I'm trying to parse the string by word in SSIS and I NEED help on vb script component.
I need to delimit my column data to the following deliminator:
"AND","OR","**", ","
I have a table like this
ID Description
1 apple AND orange, tangerine
2 avocado OR guacamole AND pineapple OR fruit
3 watermelon ** melon
And I want to parse the data like this
ID Description
1 apple
1 orange
1 tangerine
2 avocado
2 guacamole
2 pineapple
2 fruit
3 watermelon
3 melon
Thank you.
In order to parte string by words is enought a combination of replace a split:
(I assume that you know how to take ID)
split(
replace(
replace (
replace( Description, "AND", ","),
"OR", ","
),
"**", ","
), ","
)
this return a array of elements as you ask for:
id = 2
a=my_previous_functions_combination("avocado OR guacamole AND pineapple OR fruit")
for each fruit in a
do something with id and fruit
next
so far, help with vb. I don't know what you want to do in SSIS: a calculated member? a named set? Extend fact table? Read second answer part:
Second part:
To convert a row in multiples row you need a script. You can find a good example in SSIS - Script Component, Split single row to multiple rows post.