I have many variables. For brevity, assume I have two: Gender and Meal. In Stata, I am using tabout, a package that allows one to produce .tex based on Stata results that can be opened as tables in LaTeX.
In order to create a customized output with a little spacing before the variable labels, I want to assign a prefix, \hspace{0.3cm}, to the beginning of all of the values (not labels) of each variable. How can I do this automatically with a loop instead of manually doing this?
Let's say I start out with this:
label def gen 0 "Male" 1 "Female", modify
label value Gender gen
label def me 0 "Lunch" 1 "Dinner", modify
label value Meal me
I want to have a loop that will automatically add the prefix to the individual values of Gender and Meal. The end result would be the same as if I had originally done:
label def gen 0 "\hspace{0.3cm}Male" 1 "\hspace{0.3cm}Female", modify
label value Gender gen
label def me 0 "\hspace{0.3cm}Lunch" 1 "\hspace{0.3cm}Dinner", modify
label value Meal me
Note that code (from http://www.jwe.cc/2012/03/stata-latex-tables-estout/) to do a similar thing for variable labels (and NOT values) is as follows:
foreach v of varlist * {
label variable `v' `"\hspace{0.1cm} `: variable label `v''"'
}
Here is some code that produces the strings you want. I leave to you defining the new value labels and assigning to the variables. Let us know if it's useful.
clear all
set more off
*----- example -----
label def gen 0 "Male" 1 "Female", modify
*label value Gender gen
label def meal 0 "Lunch" 1 "Dinner", modify
*label value Meal me
*----- what you want -----
label dir
local rnames `=r(names)'
foreach labname of local rnames {
quietly label list `labname'
local myname
forvalues i = 0/`r(max)' {
local name : label `labname' `i', strict
local newname \hspace{0.3cm}`name'
local myname `myname' `newname'
}
display "`myname'"
}
You can make it a bit shorter, but it's all very "explicit".
help label and help extended_fcn are a must-read.
(I still insist that a solution within tabout is maybe possible; but I can't be sure.)
Edit
The following is more general, has better form and is a complete example. Extended macro functions are still the basis for the code.
clear all
set more off
*----- example database -----
sysuse voter
*----- what you want -----
foreach var of varlist _all {
local cnewname
quietly labellist `var'
if "`r(lblname)'" != "" {
*disp "`var'"
forvalues i = 1/`r(`r(lblname)'_k)' {
local val : word `i' of `r(values)'
local labval : word `i' of `r(labels)'
local newname `val' "\hspace{0.3cm}`labval'"
local cnewname `cnewname' `newname'
} // forvalues
label define newlbl`var' `cnewname'
label value `var' newlbl`var'
} // if
} // foreach
labellist
I define new value labels and re-associate with corresponding variables. You can try replacing or whatever fits your needs.
Stata doesn't understand TeX or LaTeX, at least not like this.
You could just prefix with space(s), but often Stata would just ignore them any way.
A bizarre trick I've used occasionally is to use char(160) as a pad which looks like a space but won't be trimmed.
length(trim("`=char(160)'"))
is reported as 1, i.e. char(160) is not trimmed. To check that char(160) is invisible on your machine,
di char(160)
But how this works surely depends on your TeX/LaTeX code and how it treats that character.
Related
I have a Excel-sheet, which contains variable and variable-labels. I would like to import this file into Stata. How can I do it?
Let's assume that your variable names are on the first row, and labels on the second row.
I would do:
import excel using file.xlsx, firstrow clear
foreach var of varlist _all {
local x = `var'[1]
label var `var' "`x'"
}
drop if [_n]==1
foreach var of varlist _all {
cap destring `var', replace
}
The first bit replaces the label of the variables with the variable label, which should be in the first row of your imported dataset. The second bit drops this row, and the destrings all variables for which this is possible without an error. The reason for this is that all variables will be imported as strings when you have the second row as variable labels.
This is the most typical case I encountered, but of course there may be other scenarios where you have to adopt different approaches.
I'm designing a Mastermind game, which basically compares 2 lists and marks the similarities. When a colour is found at the right place, a flag making the correct position is added and the item found on the reference list is marked off. The reference list is feeding off an array from another function. The problem is at the mark off, as any changes done to the reference list is changing also the original array, which i don't want it to happen
tempCode = mCode #mCode is the array combination randomly generated from another function
for i in range (len(uCode)): #user input array
for j in range (len(tempCode)): #temp array
if uCode[i] == tempCode[j]: # compare individual chars
if i == j: #compare position
flagMark = "*"
tempCode.insert(j+1, "x") #problem starts here
tempCode.remove(tempCode[j])
fCode.append(flagMark)
When the insert is reached both the tempCode and mCode change which it is not intended.
The code is written in a way should the user enter a combination of the same colours, thus checking the chras(the colours are just letters) and the position, and then mark them of with "x"
As it stands, when it gets to
tempCode.insert(j+1, "x")
the arrays will change to
mCode = ["B","R","x","G","Y"]
tempCode = ["B","R","x","G","Y"]
when I would just want
mCode = ["B","R","G","Y"]
tempCode = ["B","R","x","G","Y"]
See also this answer, which is a different presentation of the same problem.
Essentially, when you do tempCode = mCode, you're not making a copy of mCode, you're actually making another reference to it. Anything you do to tempCode thereafter affects the original as well, so at any given time the condition tempCode == mCode will be true (as they're the same object).
You probably want to make a copy of mCode, which could be done in either of the following ways:
tempCode = mCode.copy()
tempCode = mCode[:]
which produces a different list with the same elements, rather than the same list
I have a Matlab table and want to create an SQL INSERT statement of this line(s).
K>> obj.ConditionTable
obj.ConditionTable =
Name Data Category Description
________________ ____________ _________________ ___________
'Layout' 'STR' '' ''
'Radius' [ Inf] 'Radius_2000_inf' ''
'aq' [ 0] '0' ''
'VehicleSpeed' [ 200] 'Speed_160_230' ''
Erros when conditionTable = obj.ConditionTable(1,:);
K>> char(conditionTable.Data)
Error using char
Cell elements must be character arrays.
K>> char(conditionTable.Description)
ans =
Empty matrix: 1-by-0
problem: the [Inf] entry
problem: possibly [123] number entries
problem: '' entries
Additionally, following commands are also useless in this matter:
K>> length(conditionTable.Data)
ans =
1
K>> isempty(conditionTable.Description)
ans =
0
Target Statement would be something like this:
INSERT INTO `ConditionTable` (`Name`, `Data`, `Category`, `Description`, `etfmiso_id`) VALUES ("Layout", "STR", "", "", 618);
Yes, num2str accept a single variable of any type and will return a string, so all these operations are valid:
>> num2str('123')
ans =
123
>> num2str('chop')
ans =
chop
>> num2str(Inf)
ans =
Inf
However, it can deal with purely numeric arrays (e.g. num2str([5 456]) is also valid), but it will bomb out if you try to throw a cell array at it (even if all your cells are numeric).
There are 2 possible way to work around that to convert all your values to character arrays:
1) use an intermediate cell array
I recreated a table [T] with the same data than in your example. Then running:
%% Intermediate Cell array
T3 = cell2table( cellfun( #num2str , table2cell(T) , 'uni',0) ) ;
T3.Properties.VariableNames = T.Properties.VariableNames
T3 =
Name Data Category Description
______________ _____ _________________ ___________
'Layout' 'STR' '' ''
'Radius' 'Inf' 'Radius_2000_inf' ''
'aq' '0' '0' ''
'VehicleSpeed' '200' 'Speed_160_230' ''
produces a new table containing only strings. Notice that we had to recreate the column names (copied from the initial table), as these are not transferred into the cell array during conversion.
These method is suitable for relatively small tables, as the round trip table/cellarray/table plus the call to cellfun will probably be quite slow for larger tables.
2) Use varfun function
varfun is for Tables the equivalent of cellfun for cell arrays. You'd think that a simple
T2 = varfun( #num2str , T )
would do the job then ... well no. This will error too. If you look at the varfun code at the line indicated by the error, you'll notice that internally, data in your table are converted to cell arrays and the function is applied to that. As we saw above, num2str errors when met with a cell array. The trick to overcome that, is to send a customised version of num2str which will accept cell arrays. For example:
cellnum2str = #(x) cellfun(#num2str,x,'uni',0)
Armed with that, you can now use it to convert your table:
%% Use "varfun"
cellnum2str = #(x) cellfun(#num2str,x,'uni',0) ;
T2 = varfun( cellnum2str , T ) ;
T2.Properties.VariableNames = T.Properties.VariableNames ;
This will produce the same table than in the example 1 above. Notice that again we had to reassign the column headers on the newly created table (the irony is varfun choked trying to apply the function on the column headers, but does not re-use or return them in the output ... go figure.)
discussion: Initially I tried to make the varfun solution work (hence the T2 name of the result), and wanted to recommend this one, because I didn't like the table/cell/table conversion of the other solution. Now I have seen what goes on into varfun, I am not so sure that this solution will be faster. It might be slightly more readable in a semantic way, but if speed is a concern you'll have to try both version and choose which one gives you the best results.
for the record: num2str(cell2mat(conditionTable.Data)), works, independant if 'abc', [Inf], [0], [123.123], apparently..
I am currently attempting to parse data that is sent from an outside source serially. An example is as such:
DATA|0|4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_
This data can come in many different lengths, but the first few pieces are all the same. Each "piece" originally comes in with CRLF after, so I've replaced them with string.gsub(input,"\r\n","|") so that is why my input looks the way it does.
The part I would like to parse is:
4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_
The "4" tells me that there will be four lines total to create this file. I'm using this as a means to set the amount of passes in the loop.
The 7x5 is the font height.
The 1 is the xpos.
The 25 is the ypos.
The variable data (172-24 in this case) is the text at these parameters.
As you can see, it should continue to loop this pattern throughout the input string received. Now the "4" can actually be any variable > 0; with each number equaling a set of four variables to capture.
Here is what I have so far. Please excuse the loop variable, start variable, and print commands. I'm using Linux to run this function to try to troubleshoot.
function loop_input(input)
var = tonumber(string.match(val, "DATA|0|(%d*).*"))
loop = string.match(val, "DATA|0|")
start = string.match(val, loop.."(%d*)|.*")
for obj = 1, var do
for i = 1, 4 do
if i == 1 then
i = "font" -- want the first group to be set to font
elseif i == 2 then
i = "xpos" -- want the second group to be set to xpos
elseif i == 3 then
i = "ypos" -- want the third group to be set to ypos
else
i = "txt" -- want the fourth group to be set to text
end
obj = font..xpos..ypos..txt
--print (i)
end
objects = objects..obj -- concatenate newly created obj variables with each pass
end
end
val = "DATA|0|4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_"
print(loop_input(val))
Ideally, I want to create a loop that, depending on the var variable, will plug in the captured variables between the pipe deliminators and then I can use them freely as I wish. When trying to troubleshoot with parenthesis around my four variables (like I have above), I receive the full list of four variables four times in a row. Now I'm having difficulty actually cycling through the input string and actually grabbing them out as the loop moves down the data string. I was thinking that using the pipes as a means to delineate variables from one another would help. Am I wrong? If it doesn't matter and I can keep the [/r/n]+ instead of each "|" then I am definitely all for that.
I've searched around and found some threads that I thought would help but I'm not sure if tables or splitting the inputs would be advisable. Like these threads:
Setting a variable in a for loop (with temporary variable) Lua
How do I make a dynamic variable name in Lua?
Most efficient way to parse a file in Lua
I'm fairly new to programming and trying to teach myself. So please excuse my beginner thread. I have both the "Lua Reference Manual" and "Programming in Lua" books in paperback which is how I've tried to mock my function(s) off of. But I'm having a problem making the connection.
I thank you all for any input or guidance you can offer!
Cheers.
Try this:
val = "DATA|0|4|7x5|1|25|174-24|7x5|1|17|TERW|7x5|1|9|08MN|7x5|1|1|_"
val = val .. "|"
data = val:match("DATA|0|%d+|(.*)$")
for fh,xpos,ypos,text in data:gmatch("(.-)|(.-)|(.-)|(.-)|") do
print(fh,xpos,ypos,text)
end
I'm trying to use get() to access a list element in R, but am getting an error.
example.list <- list()
example.list$attribute <- c("test")
get("example.list") # Works just fine
get("example.list$attribute") # breaks
## Error in get("example.list$attribute") :
## object 'example.list$attribute' not found
Any tips? I am looping over a vector of strings which identify the list names, and this would be really useful.
Here's the incantation that you are probably looking for:
get("attribute", example.list)
# [1] "test"
Or perhaps, for your situation, this:
get("attribute", eval(as.symbol("example.list")))
# [1] "test"
# Applied to your situation, as I understand it...
example.list2 <- example.list
listNames <- c("example.list", "example.list2")
sapply(listNames, function(X) get("attribute", eval(as.symbol(X))))
# example.list example.list2
# "test" "test"
Why not simply:
example.list <- list(attribute="test")
listName <- "example.list"
get(listName)$attribute
# or, if both the list name and the element name are given as arguments:
elementName <- "attribute"
get(listName)[[elementName]]
If your strings contain more than just object names, e.g. operators like here, you can evaluate them as expressions as follows:
> string <- "example.list$attribute"
> eval(parse(text = string))
[1] "test"
If your strings are all of the type "object$attribute", you could also parse them into object/attribute, so you can still get the object, then extract the attribute with [[:
> parsed <- unlist(strsplit(string, "\\$"))
> get(parsed[1])[[parsed[2]]]
[1] "test"
flodel's answer worked for my application, so I'm gonna post what I built on it, even though this is pretty uninspired. You can access each list element with a for loop, like so:
#============== List with five elements of non-uniform length ================#
example.list=
list(letters[1:5], letters[6:10], letters[11:15], letters[16:20], letters[21:26])
#===============================================================================#
#====== for loop that names and concatenates each consecutive element ========#
derp=c(); for(i in 1:length(example.list))
{derp=append(derp,eval(parse(text=example.list[i])))}
derp #Not a particularly useful application here, but it proves the point.
I'm using code like this for a function that calls certain sets of columns from a data frame by the column names. The user enters a list with elements that each represent different sets of column names (each set is a group of items belonging to one measure), and the big data frame containing all those columns. The for loop applies each consecutive list element as the set of column names for an internal function* applied only to the currently named set of columns of the big data frame. It then populates one column per loop of a matrix with the output for the subset of the big data frame that corresponds to the names in the element of the list corresponding to that loop's number. After the for loop, the function ends by outputting that matrix it produced.
Not sure if you're looking to do something similar with your list elements, but I'm happy I picked up this trick. Thanks to everyone for the ideas!
"Second example" / tangential info regarding application in graded response model factor scoring:
Here's the function I described above, just in case anyone wants to calculate graded response model factor scores* in large batches...Each column of the output matrix corresponds to an element of the list (i.e., a latent trait with ordinal indicator items specified by column name in the list element), and the rows correspond to the rows of the data frame used as input. Each row should presumably contain mutually dependent observations, as from a given individual, to whom the factor scores in the same row of the ouput matrix belong. Also, I feel I should add that if all the items in a given list element use the exact same Likert scale rating options, the graded response model may be less appropriate for factor scoring than a rating scale model (cf. http://www.rasch.org/rmt/rmt143k.htm).
'grmscores'=function(ColumnNameList,DataFrame) {require(ltm) #(Rizopoulos,2006)
x = matrix ( NA , nrow = nrow ( DataFrame ), ncol = length ( ColumnNameList ))
for(i in 1:length(ColumnNameList)) #flodel's magic featured below!#
{x[,i]=factor.scores(grm(DataFrame[, eval(parse(text= ColumnNameList[i]))]),
resp.patterns=DataFrame[,eval(parse(text= ColumnNameList[i]))])$score.dat$z1}; x}
Reference
*Rizopoulos, D. (2006). ltm: An R package for latent variable modelling and item response theory analyses, Journal of Statistical Software, 17(5), 1-25. URL: http://www.jstatsoft.org/v17/i05/