Naming collection of variables at once in SAS - arrays

I am trying to create 46 variables, indexed from 0-45 dependent on 3 other variables, each of which is indexed from 0-45. It seems as though the array approach would be the most straightforward but I can't get it to work. So i have variables a_0,...,a_45,b_0,...,b_45,c_0,...,c_45 and i want to create d_i=a_i+b_i+c_i but I'm having some difficulty.
Attempt:
data test;
set test;
array d [0:45];
array a [0:45] a_0-a_45;
array b [0:45] b_0-b_45;
array c [0:45] c_0-c_45;
do i=0 to 45;
d[i]=a[i]+b[i]+c[i];
end;
run;
1) I can't seem to get the index from 0.
2) Whenever I run checks, the variables never add up in the intended way.

try changing array d defintion.
array d [0:45];
to
array d [0:45] d0-d45;
In case of array d [0:45] it creates d1 to d46 whereas in case of array d [0:45] d_0-d_45 you explicitly index from 0 to 45.

If you don't tell SAS what variable names to use for the array it will just create names using the array name and adding a numeric suffix. So when you wrote
array d [0:45];
You told it to create 46 variables named d1 to d46.
You could tell it what names to use.
array d [0:45] d_0 - d_45 ;
Also in the code you posted it doesn't really matter whether your index variable's value matches the numeric suffix on the variable names. So why not make it much simpler.
array a a_0-a_45;
array b b_0-b_45;
array c c_0-c_45;
array d d_0-d_45;
do i=1 to dim(a);
d(i)=a(i)+b(i)+c(i);
end;
You could also just number your variables starting with 1 instead of Zero and save a lot of headache.

Related

Array of sets in Matlab

Is there a way to create an array of sets in Matlab.
Eg: I have:
a = ones(10,1);
b = zeros(10,1);
I need c such that c = [(1,0); (1,0); ...], i.e. each set in c has first element from a and 2nd element from b with the corresponding index.
Also is there some way I can check if an unknown set (x,y) is in c.
Can you all please help me out? I am a Matlab noob. Thanks!
There are not sets in your understanding in MATLAB (I assume that you are thinking of tuples on Python...) But there are cells in MATLAB. That is a data type that can store pretty much anything (you may think of pointers if you are familiar with the concept). It is indicated by using { }.
Knowing this, you could come up with a cell of arrays and check them using cellfun
% create a cell of numeric arrays
C = {[1,0],[0,2],[99,-1]}
% check which input is equal to the array [1,0]
lg = cellfun(#(x)isequal(x,[1,0]),C)
Note that you access the address of a cell with () and the content of a cell with {}. [] always indicate arrays of something. We come to this in a moment.
OK, this was the part that you asked for; now there is a bonus:
That you use the term set makes me feel that they always have the same size. So why not create an array of arrays (or better an array of vectors, which is a matrix) and check this matrix column-wise?
% array of vectors (there is a way with less brackets but this way is clearer):
M = [[1;0],[0;2],[99;-1]]
% check at which column (direction ",1") all rows are equal to the proposed vector:
lg = all(M == [0;2],1)
This way is a bit clearer, better in terms of memory and faster.
Note that both variables lg are arrays of logicals. You can use them directly to index the original variable, i.e. M(:,lg) and C{lg} returns the set that you are looking for.
If you would like to get logical value regarding if p is in C, maybe you can try the code below
any(sum((C-p).^2,2)==0)
or
any(all(C-p==0,2))
Example
C = [1,2;
3,-1;
1,1;
-2,5];
p1 = [1,2];
p2 = [1,-2];
>> any(sum((C-p1).^2,2)==0) # indicating p1 is in C
ans = 1
>> any(sum((C-p2).^2,2)==0) # indicating p2 is not in C
ans = 0
>> any(all(C-p1==0,2))
ans = 1
>> any(all(C-p2==0,2))
ans = 0

Loop in lua is supposed to modify values of an array but it does not

Here's the loop:
array={0x, 0y, 1x, 1y}
for i, v in ipairs(array) do
if (i%2)==0 then
array[i]=v+valuex
else
array[i]=v+valuey
end
end
What i think it should do is cycle through the array and add either the variable 'valuex' if the position of the array variable is pair and 'valuey' if it's not: array[i] is the position, and I add 'valuex/y' to its 'v' value, but in the end nothing end up happening.
In the other hand, this code works, and it's what i'm trying to make the loop achieve:
0x=0x+valuex
1x=1x+valuex
0y=0y+valuey
1y=1y+valuey
I really can't get my hand on the reason the loop doesn't do that, but in the same time, you've guessed it, i'm a beginner in lua and in programming in general so i'd appreciate if you could lend me a hand.
Thanks.
Assuming, as you state in a comment, that 0x et. al. are in fact variables, your code was never going to work.
Variables are not values; they're variables. Variables store values, but they are not themselves values.
When you created your array, you copied the values inside of those variables into the array. Those array entries are modified, but there is no association between the array entries and where they got their values from.
If you want to manipulate the variables themselves, then they would have to be part of some table (perhaps the global table), the array indices would have to be the string names of those values, and your modifying function would have to use v to access the variable from the table. Assuming your "0x" variables are entries in the global table, the code would look something like this:
array={"0x", "0y", "1x", "1y"} --Storing string names of the variables.
for i, v in ipairs(array) do
if (i % 2) == 0 then
_G[v] = _G[v] + valuex
else
_G[v] = _G[v] + valuey
end
end

Matlab array storing through loop

I have a for loop and each value a{i} b{i} c{i} is equal each time with a specific number. So I was wondering how can I put all those value in an array through loop. The way that I am using I mean this one [a{i};b{i};c{i}] it seems that it doesn't work! If I keep 2 out of three values is working but I want the data from all of the values (a b c)
You can see the (pseudo)code below:
for i=1:number of cells
Cell{i}.Tri=[a{i};b{i};c{i}]
end
cell2mat is what you need:
a = num2cell(rand(1,10));
b = num2cell(rand(1,10));
c = num2cell(rand(1,10));
abc = cell2mat([a;b;c]);
This can be done without a for loop by using cellfun combined with the cat function. EDIT: As noted in the comments, cellfun is itself a loop.
% Create all variables
a{1}=rand(10);
a=repmat(a,10,1);
b=a;
c=a;
% Add a cell array of equal size to a. The contents of each cell are the dimension along which to concatenate.
catarg=num2cell(ones(size(a)))
% Do the concatenation
d=cellfun(#cat,catarg,a,b,c,'UniformOutput',false);

Arrays in matlab

I have a structure names eye_record which has 6 fields, one of which is x_pos_measured_deg:[1800x1 double]
I want to declare an array in such a way that using for loop, i can get all values of that specific field into a new array and do some work on them. Can anyone show me how to do that? here is m code:
arr=zeros(1,1800);
for t=1:length(eye_record);
arr(t)= eye_record(t).x_pos_measured_deg;
end
it gives me this error: In an assignment A(I) = B, the number of elements in B and I must be the same. How can i fix this? or how should i declare my array so that it won't give me this error? I want all the objects or values, which are in x_pos_measured_deg field to go into my new array.
Your eye_record is struct, not array, so you can not use indexing with eye_record. Your eye_record.x_pos_measured_deg is array and you have to loop through it. So the loop should be:
arr=zeros(1,1800);
for t=1:length(eye_record.x_pos_measured_deg)
arr(t)= eye_record.x_pos_measured_deg(t);
end
But actually, you can assign values directly like:
arr=zeros(1,1800);
arr = eye_record.x_pos_measured_deg';
since you declared arr to have size of 1x1800, and eye_record.x_pos_measured_deg has size of 1800x1.
Without arr=zeros(1,1800);, then no ' at the end:
arr = eye_record.x_pos_measured_deg;

FORTRAN - Assigning an array value to variable

Is there a way to get the value of an array to the shape of a variable? Even when I select a single value of an array, say A(1:1, 1:1), it still complains when I compile and want to assign this to a variable:
Error: Incompatible ranks 0 and 1 in assignment at (1)
The goal in the end is something like this:
H = MAXVAL(matrix) - epsilon
IF ( matrix(i:i, i:i) >= H ) THEN
...
but I cannot make this comparison because H is a variable and matrix(i:i, i:i) a 1x1 array. Is the only possibility for this to work to make H and array, too?
Thank you for your help!
Do not specify a range, use a single element:
A(1,1)=1
Your statement would then read:
H = MAXVAL(matrix) - epsilon
IF ( matrix(i, i) >= H ) THEN
Background:
Fortran allows you to work on sub-arrays like:
A(1:10,2:5)
which would be a 10x4 array. So A(1:1,1:1) is in fact an array (1x1) (as you noted). A(1,1), on the other hand, is a scalar and can be treated as such.

Resources