There's this piece of code with me, which.
1. opens two files,"blue.csv","red.csv".
2. calculates the value and based on if-else statement, prints the output to the corresponding file.
fp1 = fopen('red.csv','w');
fp2 = fopen('blue.csv','w');
for x = 0:100:2500,
for y = 0:100:2500,
vector = [x , y]
vara = gOfX(vector,mu1,finalcovariance) ;
varb = gOfX(vector,mu2,finalcovariance) ;
if vara < varb
fprintf(fp2,'%d,%d\n',x,y);
fprintf('vara-varb is -------negative\n ');
else
fprintf('%d,%d\n',x,y);
fprintf(fp1,'%d,%d\n',x,y);
fprintf('vara-varb is ---------------------positive\n ');
endif;
endfor
endfor
The problem is, the fprintf(fp1,'%d,%d\n',x,y); statement in else condition is not working,i.e., I am unable to get anything in the file specified byfp1 although the statements above and below are perfectly working fine(gOfX is therefore working fine too).
I have tried changing the file pointers etc. but none of that worked.
Moreover, if I change the if vara < varb condition to if vara > varb, then I don't get anything printed into file pointed by fp2( thus to me,it seems the problem with > part).
Any solution could drastically save my time in finishing my assignment.
Thanks !
Use Octave's fflush to flush the buffer
Don't forget to close your files using fclose.
Related
I'm trying to understand how to code something along the lines of "NOT IN the LIST" type of logic in SAS.
I figured I could do "NOT" + "IN" as something like below.
Data work.OUT;
Set work.IN;
If VAR=1 then OUTPUT=1;
else if VAR=2 then OUTPUT=2;
else if VAR NOT in (1,2) then OUTPUT=3;
else OUTPUT=4;
run;
When I export the dataset all I see is OUTPUT=3 for all records. So something is happening in the derivation and it's transforming all VAR values into OUTPUT 3 values for some reason. Even though I know for a fact that other values exist in the VAR.
I don't understand what the problem is? Can we not combine NOT+IN operators? Alternatively, do you have any other ways of coding this type of logic in SAS? I rather not code each bit of code since I have more than 300 unique values for VAR
Welcome to Stack Overflow Alejandro. Your code assigns values 1 2 or 3 depending on what values are in the variable called var:
data in;
do var = 1 to 5;
output;
end;
run;
Data work.OUT;
set work.IN;
If VAR=1 then OUTPUT=1;
else if VAR=2 then OUTPUT=2;
else if VAR NOT in (1,2) then OUTPUT=3;
else OUTPUT=4;
run;
Your code says check for var = 1 then check for var = 2 and then check if it is not 1 or 2. The final else is never checked because a var will be 1 or 2 or not 1 or 2.
If you have a pile of if checks, you can use a select/when/otherwise/end block. It will check a series of rules (in the order you type them) and then will do something based on whichever rule is true first.
data out;
set in;
select;
when(var = 1) output = 1;
when(var = 2) output = 2;
when(var < 5) output = 3;
when(.) output = -9999999;
otherwise output = 42;
end;
run;
I hope that helps. If not please send up another flare.
Variable name is PRC. This is what I have so far. First block to delete negative values. Second block is to delete missing values.
data work.crspselected;
set work.crspraw;
where crspyear=2016;
if (PRC < 0)
then delete;
where ticker = 'SKYW';
run;
data work.crspselected;
set work.crspraw;
where ticker = 'SKYW';
where crspyear=2016;
where=(PRC ne .) ;
run;
Instead of using a function to remove negative and missing values, it can be done more simply when inputting or outputting the data. It can also be done with only one data step:
data work.crspselected;
set work.crspraw(where = (PRC >= 0 & PRC ^= .)); * delete values that are negative and missing;
where crspyear = 2016;
where ticker = 'SKYW';
run;
The section that does it is:
(where = (PRC >= 0 & PRC ^= .))
Which can be done for either the input dataset (work.crspraw) or the output dataset (work.crspselected).
If you must use a function, then the function missing() includes only missing values as per this answer. Hence ^missing() would do the opposite and include only non-missing values. There is not a function for non-negative values. But I think it's easier and quicker to do both together simultaneously without a function.
You don't need more than your first test to remove negative and missing values. SAS treats all 28 missing values (., ._, .A ... .Z) as less than any actual number.
I have two FORTRAN codes that are almost identical except for one line of code, and the FILE names in my OPEN statements. This one different line of code produces the two distinct final results I am looking for hence why I have two different codes.
I would like to merge these two codes into one if possible.
What is the best way to do this? To be specific, I want to have only one FORTRAN file which will run either FORTRAN 'code'. That way, when I need to edit either code I am only doing so in one file. Now having two different files it is a bit of an inconvenience.
A simplified example code for the two different files are below, Sample.f90 and Sample2.f90. What IF statements can I use that will allow me to choose which initial condition to use, either R = COS(x+y) or R = SIN(x+y)? I am not familiar at all with how to use IF statements for this.
PROGRAM SAMPLE !Sample.f90
USE TestModule
IMPLICIT NONE
REAL, DIMENSION(-10,10) :: R
INTEGER :: i,j
REAL :: x,y
OPEN(UNIT = 100, FILE = 'Sample1.dat')
DO j = -10,10
DO i = -10,10
x = i*0.1
y = j*0.1
R(i,j) = COS(x+y)
END DO
END DO
WRITE(100,*) R(0,1)
END PROGRAM
!The next program is of the form:
PROGRAM SAMPLE2 !Sample2.f90
USE TestModule2
IMPLICIT NONE
REAL, DIMENSION(-10,10) :: R
INTEGER :: i,j
REAL :: x,y
OPEN(UNIT = 101, FILE = 'Sample2.dat')
DO j = -10,10
DO i = -10,10
x = i*0.1
y = j*0.1
R(i,j) = SIN(x+y)
END DO
END DO
WRITE(101,*) R(0,1)
END PROGRAM
There is the run-time approach. You have an interactive query of which version you want to run, then an IF statement that selects one of the two alternative statements based on that. Another version of this is to read the choice from the command line using the intrinsic GET_COMMAND_ARGUMENT.
A compile-time approach would be to use the preprocessor to select one statement or the other by defining a symbol (e.g., SYM) or not with your compile command (-DSYM), that using #ifdef SYM, #else, #endif to select which Fortran statement to compile.
Some code fragments. Declare choice as an integer and filename as a string.
read (*, '( "Input choice: " )', advance="no" ) choice
or
call GET_COMMAND_ARGUMENT ( 1, string )
read (string, *) choice
then:
if (choice /=1 .AND. choice /=2 ) then
write (*, *) "bad choice"
stop
end if
if (choice == 1) then
filename = "FileOne.txt"
else
filename = "FileTwo.txt"
end if
open (file=filename, ....
and similar IF statement to setup the initial condition.
Or instead you can include or not -DCHOICEONE in your compilation command and use preprocessor lines:
#ifdef CHOICEONE
filename = "FileOne.txt"
#else
filename = "FileTwo.txt"
#endif
etc.
I have some SAS code along the lines of:
DATA MY_SAMPLE;
SET SAMPLE;
BY A;
IF A = 1 THEN B = 1;
ELSE IF A ^= 1 THEN B = 0;
ELSE IF MISSING(A) THEN B = .;
IF FIRST.A;
RUN;
which is returning a set with 0 observations (it shouldn't do this). I have sorted the data by A and tried reading the data into an intermediate dataset before applying the IF FIRST.A but get the same results.
Am I missing something completely obvious? I use the FIRST and LAST all of the time!
Agree with #Robert, the sample code should output records, assuming there are records in your input data and it is sorted.
I would double-check the log from your real program/data, and make sure there are no errors, and that the input dataset has records.
If that doesn't help, I would add some debugging PUT statements, something like below (untested):
DATA MY_SAMPLE;
SET SAMPLE;
BY A;
IF A = 1 THEN B = 1;
ELSE IF A ^= 1 THEN B = 0;
ELSE IF MISSING(A) THEN B = .; *This will never be true ;
put "Before subsetting if " (_n_ A first.A)(=) ;
IF FIRST.A;
put "After subsetting if " (_n_ A first.A)(=) ;
RUN;
As Robert noted, as written your Else if Missing(A) would never be true, because if A is missing the prior Else if A ^= 1 will evaluate to true because SAS uses binary logic (true/false), not trinary logic(true/false/null).
Also I would check for any stray OUTPUT statements in your code.
Checked the log; checked the input; closed MSSQL down; opened it up again and lo and behold, code worked first time. Thanks for the downgrade, but I didn't realize that MSSQL is prone to twitches!
I want to write six temp data files from my original data keeping the following variables:
temp1: v1-v18
temp2: v1-v5 v19-v31
temp3: v1-v5 v32-v44
temp4: v1-v5 v45-v57
temp5: v1-v5 v58-v70
temp6: v1-v5 v71-v84
I have tried the following:
forvalues i =1(1)6 {
preserve
local j = 6 + (`i'-1)*13
local k = `j'+12
keep v1-v18 if `j'==6
keep v1-v5 v`i'-v`k' if `i'>6 & `j'<71
keep v1-v5 v71-v84 if `j'==71
export delimited using temp`i'.csv, delimiter(";") novarnames replace
restore
}
I get an invalid syntax error. The problem lies with the keep statements. Specifically the if condition with a local macro seems to be against syntax rules.
I think part of your confusion is due to misunderstanding the if qualifier vs the if command.
The if command evaluates an expression: if that expression is true, it executes what follows. The if command should be used to evaluate a single expression, in this case, the value of a macro.
You might use an if qualifier, for example, when you want to regress y x if x > 2 or replace x = . if x <= 2 etc. See here for a short description.
Your syntax has other issues too. You cannot have code following on the same line as the open brace in your forvalues loop, or again on the same line as your closing brace. You also use the local i to condition your keep. I think you mean to use j here, as i simply serves to iterate the loop, not identify a variable suffix.
Further, the logic here seems to work, but doesn't seem very general or efficient. I imagine there is a better way to do this but I don't have time to play around with it at the moment - perhaps an update later.
In any case, I think the correct syntax most analogous to what you have tried is something like the following.
clear *
set more off
set obs 5
forvalues i = 1/84 {
gen v`i' = runiform()
}
forvalues i =1/6 {
preserve
local j = 6 + (`i'-1)*13
local k = `j'+12
if `j' == 6 {
keep v1-v18
}
else if `j' > 6 & `j' < 71 {
keep v1-v5 v`j'-v`k'
}
else keep v1-v5 v71-v84
ds
di
restore
}
I use ds here to simply list the variables in the data followed by di do display a blank line as a separator, but you could simply plug back in your export and it should work just fine.
Another thing to consider if you truly want temp data files is to consider using tempfile so that you aren't writing anything to disk. You might use
forvalues i = 1/6 {
tempfile temp`i'
// other commands
save `temp`i''
}
This will create six Stata data files temp1 - temp6 that are held in memory until the program terminates.