I have a basic question about Stata. I have programming experience in R but I've started a new job where Stata is the main language. I'm currently diving into Stata on my own and sometimes it's hard to understand how to do simple things.
I've trying to get 5 random numbers between 3 and 50 but without success.
In R, any of these would work:
floor(runif(5, min=3, max=50))
16 39 11 11 5 # output
sample(3:50, 5, replace=TRUE)
28 13 5 36 19 # output
But I'm not sure how to do this in Stata, specifically how to return random numbers within the desired range (3:50). Any pointers would be appreciated. I found the runiform() function but I don't think I can get the same output.
Is this what you want?
set obs 5
generate rnum = runiform(3, 50)
You are basically creating a dataset first and then generating a variable with the desired properties.
Related
In Julia, I would like to write a function that prompts the user multiple times for matrix input, and then stores their inputs into an array. I have tried the following so far:
function acceptlist()
matrix_array=[]
while true:
matrix_input=read() #don't know what function to use?
if matrix_input="quit"
break
end
push!(matrix_array, matrix_input)
end
end
However, I am not sure how to accept matrix inputs in the way I desire. Is there any way for me to accept matrix inputs from the user? Also, I would like to user to NOT have to manually enter the matrices into the function (using readdlm or something similar). For example, I want the user to be able to read in the matrix from another file, assign it to some variable, and then enter that variable into this function acceptlist() as user input.
This code might provide an example of what you need (sorry, but a bit tired for a full answer):
m = Matrix{Int}(undef,0,0)
while true
s = readline()
if length(s)<1
break
end
r = hcat(parse.(Int, split(s))...)
m = size(m,1)>0 ? vcat(m,r) : r
end
After running, m should have an Int matrix. Same logic would apply to Float64, and many more validations can be added depending on the level and context of the code.
For example, a run could look like:
1 2 3
2 3 4
4 5 6
julia> m
3×3 Matrix{Int64}:
1 2 3
2 3 4
4 5 6
If you are on Linux or Mac you can just be using DelimitedFiles and run readdlm(stdin). The user will need to press Ctrl+D once she or he is done.
See this sample Julia session on Ubuntu:
julia> readdlm(stdin;comments=true)
1 2 3
4 5 6 # I now press Ctrl+D
2×3 Matrix{Float64}:
1.0 2.0 3.0
4.0 5.0 6.0
This will however not work on Windows as creators of some operating systems never found out how to make a working text terminal ;-)
When I switch on the "local line numbering" option in SciNotes, I get a strange effect. The line numbers show as local (starting with the "function" line) for some of my functions, but global (counting from the beginning of the code file) for others.
My first thought was that a function wasn't ended properly (too few "end" instructions wrt the number of opened loops, ifs and other such), but then my code would crash, which it doesn't. Also, indentation looks fine when I auto-adjust it.
It doesn't very much get in my way, but I wonder if it isn't a symptom of something more serious cooking under the surface. Has anybody had a similar experience?
FWIW I'm using Scilab 6.0.2 under Windows 10.
I think I have found the source of the "problem". Line numbering only gets local in a function whose first line (the one with the "function" keyword) is not terminated with a semicolon.
Like this:
1 // This is my fantastic power program
2 clear;
3 clc;
4 cd "c:\myDir\Scilab\Sandbox\FunAndGames"
5
6 function S=square(x); // <-- now you see it
7 S=x*x; // (the semicolon, I mean)
8 endfunction;
9
1 function C=cube(x) // <-- now you don't
2 C=x*x*x;
3 endfunction;
13
14
15 // Now the body of my program:
16
17 X=zeros(5,5);
18 ....
I am new to SAS and have been using R most of the time. I am stuck with a simple and frustrating issue. All I want to do is to create a simple 3 X 3 matrix in SAS. But it throws an error. I need some help in understanding what's going on. The SAS documentation is not very helpful.
data matrixTest;
input Y $ X;
cards;
4 0
3 1
1 1
;
run;
/*Convert X to a categorical variable*/
data matrixTest;
set matrixTest;
if X = 0 then X = "0";
else X = "1";
run;
/*Get design matrix from the regression model*/
proc transreg data=matrixTest design;
model class(X/ zero=last);
output out=input_mcmc(drop=_: Int:);
run;
mX = {5 4 3, 4 0 4, 7 10 3};
And I get the following error when creating the matrix mX:
ERROR 180-322: Statement is not valid or it is used out of proper order.
Your error is that SAS is not a matrix language. SAS is more like a database language; the unit of operation is the dataset, analogous to a SQL table or a dataframe in R or Python.
SAS does have a matrix language built into the system, SAS/IML (interactive matrix language), but it's not part of base SAS and isn't really what you use in the context you're showing. The way you enter data as part of your program is how you did it in the first data step, with datalines.
Side note: You're also showing some R tendencies in the second data step; you cannot convert a variable's type that way. SAS has only 'numeric' and 'character', so you don't have 'categorical' data type anyway; just leave it as is.
Do not use the same data set name in the SET and DATA statements. This makes it hard to debug because you've destroyed your initial data set.
You cannot change types on the fly in SAS. If a variables i character it stays character.
If a variable is numeric, you assign values without quotes, quotes are used for character variables.
Your attempt to create a categorical variable doesn't make sense given the fact that it's already 0/1. Make sure your test data is reflective of your actual situation.
I'm not familiar with PROC TRANSREG so I cannot comment on that portion but those are the issues you're facing now.
As someone else mentioned, SAS is not a matrix language, it processes data line by line instead which means it can handle really, really large data sets because it doesn't have to load it into memory.
Your data set, matrixTest is essentially a data set and ready to go. You don't need to convert it to a matrix or 'initialize' it.
If you want a data set with those values then create that as a data set:
data mx;
input var1-var3;
cards;
5 4 3
4 0 4
7 10 3
;
run;
Basically, what I want to do is look at the range information of a unified diff and know exactly which lines of code I should pay attention to.
For instance, this:
## -1827,7 +1827,7 ##
This tells me that in total only 1 line has changed, because the diff shows 3 lines above and below the change (so 7 - 6 = 1), and it also points me to the line 1830 (i.e. 1827 + 3).
To be more pedantic, this particular range information actually tells me that at line 1830, a line was removed (-), and at line 1830 a line was added (+).
Or to make that more obvious consider this range information for another diff:
## -878,15 +878,13 ##
What this is telling me is that at line 881 (878 + 3) 9 lines were deleted (15 - 6), but at line 881 only 7 lines were added (13 - 6).
So the question is, using a regex or some other Ruby string method, how do I pull out the above information easily?
i.e. how do I easily pull out this info:
Both The line numbers (i.e. just the 1827 or 878), which I can then add + 3 to determine the actual inline number I care about. It has to be both because both lines may not always be identical.
The number of lines affected (aka the 7, 15 or 13 right after the , in the above examples)
While I do that, how do I make sure to track the operation (addition or deletion) for each of the operations.
I tried slicing the string and going directly for a character -- e.g. myString[3] which gives me -, but that's the only character it reliably works for because the line numbers can be 1, 10, 100, 1000, 10000, etc. So the only way is to just scan the string and then parse it.
Edit 1
To add some code to show what I have tried.
Assume I have the contents of a diff in a variable called #diff_lines:
#diff_lines.each do |diff_line|
if diff_line.start_with?("##")
del_line_num_start = diff_line.split(/## /).second.split.first.split(/-/).second.split(/,/).first.to_i + 3
num_deleted_lines = diff_line.split(/## /).second.split.first.split(/-/).second.split(/,/).second.to_i - 6
add_line_num_start = diff_line.split(/## /).second.split.second.split(/\+/).second.split(/,/).first.to_i + 3
num_added_lines = diff_line.split(/## /).second.split.second.split(/\+/).second.split(/,/).second.to_i - 6
As you can see, the above works....but it is quite horrendous to look at and is OBVIOUSLY not very DRY.
Ideally I would like to be able to achieve the same thing, but just cleaner.
The general idea is to write a regular expression that has capture groups in it ((...)) to pick apart that string into something useful. For example:
diff_line.match(/\A##\s+\-(\d+),(\d+)\s+\+(\d+),(\d+)\s+##/)
This yields a MatchData object on a successful match. You can then apply this to some variables like:
if (m = diff_line.match(...))
a_start, a_len, b_start, b_len = m[1..4].map(&:to_i)
end
Then you can do whatever computations you need to do with these numbers.
If you're ever having trouble visualizing what a regular expression does, try a tool like Rubular to better illustrate the internals.
I have 10 images and I want them to be prompt out randomly. What code should I use? I'm still an amateur so I hope I could get some answers here... The images are named like 'pic1', 'pic2' and so on. is it possible to get the number from the file name and use Math.random() ?
Store the pics in an Array.
Say array index is from 0 to 9
Use Java Math.random to get random number.
You need to multiply its result by 10 get indexes in your range