In SAS/IML, I'm doing the following:
matrix = {1 2 3 4 5, 2 3 1 2 3, 8 4 8 1 1};
empty = j(5,5);
do i=1 to 5;
empty[i,] = matrix[1,];
end;
So I want to replace the ith row of "empty" with the first row of matrix, but this code doesn't work. How can I replace entire rows of a matrix like this?
If you are trying to replace every row of 'empty' with matrix[1,], I don't see any thing wrong with the code.
Related
I would like to know if it's possible to select the 5 minimum or maximum values by rows with IML ?
This is my code :
Proc iml ;
use table;
read all var {&varlist} into matrix ;
n=nrow(matrix) ; /* n=369 here*/
p=ncol(matrix); /* p=38 here*/
test=J(n,5,.) ;
Do i=1 to n ;
test[i,1]=MIN(taux[i,]);
End;
Quit ;
So I would like to obtain a matrix test that contains for the 1rst column the maximal minimum value, then for the 2nd column the minimum value of my row EXCEPTING the 1rst value, etc...
If you have any idea ! :)
Event if it's not with IML (but with SAS : base, sql..)
So for example :
Data test; input x1-x10 ; cards;
1 9 8 7 3 4 2 6
9 3 2 1 4 7 12 -2
;run;
And I would like to obtain the results sorted by row:
1 2 3 4 6 7 8 9
-2 1 2 3 4 7 12
in order to select my 5 minimum values in another table :
y1 y2 y3 y4 y5
1 2 3 4 6
-2 1 2 3 4
Read the article "Compute the kth smallest data value in SAS"
Define the modules as in the article. Then use the following:
have = {1 9 8 7 3 4 2 6,
9 3 2 1 4 7 12 -2};
x = have`; /* transpose */
ord = j(5,ncol(x));
do j = 1 to ncol(x);
ord[,j] = ordinal(1:5, x[,j]);
end;
print ord;
If you have missing values in your data and want to exclude them, use the SMALLEST module instead of the ORDINAL module.
You can use call sort() in PROC IML to sort a column. Because you want to separate the columns and not sort the whole matrix, extract the column, sort it, and then update the original.
You want to sort rows, so transpose your matrix, do the sorting, and then transpose back.
proc iml;
have = {1 9 8 7 3 4 2 6,
9 3 2 1 4 7 12 -2};
print have;
n = nrow(have);
have = have`; /*Transpose because sort works on columns*/
do i=1 to n;
tmp = have[,i];
call sort(tmp,1);
have[,i]=tmp;
end;
have = have`;
want = have[,1:5];
print want;
quit;
I have a dataset with 10,000 observations. I want to program a variable that iterates through the dataset and counts row numbers as 1, 2, 3, then resets again at 1. So, if the variable was "count" then row 1, count=1, row 2, count=2, row 3, count=3, but row 4, count=1, row 5 count=2, etc. This program is in SAS.
In the data step, you can create a counter variable using _N_ and the modulo command:
counter = mod(_N_-1,3) + 1
Should give you:
Index Counter
1 1
2 2
3 3
4 1
5 2
6 3
. .
. .
. .
That's pretty easy.
data want;
set have;
count=mod(_N_-1,3)+1;
run;
This is a question in Maple.
I understand in terms of java that I want a count and an increment but my logic doesn't convert as simply to maple code.
I have an very long list of numbers LIST (196) that I wish to turn into a 14x14 Array but using the convert(LIST,Array) only gives me a 1 dimensional array.
In Maple code, this will give me my first column.
j:=1;
for i from 1 to 14 do
B[i,j]:=Longlistvalue[i];
end do;
It's clear that my second column comes from t=2 and s from 15 to 24 but I'm struggling to put this into a loop.
Surely there is either a loop I can use for this or a maple command that puts the first 14 into the first row (or column) then the next 14 into the next row/column etc?
My most recent attempt gets me
B:=Array(1..14,1..14):
n:=1;
m:=14;
for j from 1 to 14 do
for i from n to m do
B[i,j]:=Longlistvalue[i];
end do;
n:=n+14;
m:=m+14;
end do;
But not it states that my array is out of range (because the s in B[i,j] must be less than 15).
Is there a way to get around this by means of a more efficient loop?
The Array (or Matrix) constructor can be used to do this directly, using an operator to assign the entries.
You can lay the list entries down into the Array either by column or by row. Adjust the example to fit your case where m=14 and n=14.
m,n := 3,4:
L:=[seq(i,i=1..m*n)]; # you got your list in another way
L := [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
Array(1..m,1..n,(i,j)->L[(j-1)*m+i]);
[1 4 7 10]
[ ]
[2 5 8 11]
[ ]
[3 6 9 12]
Array(1..m,1..n,(i,j)->L[(i-1)*n+j]);
[1 2 3 4]
[ ]
[5 6 7 8]
[ ]
[9 10 11 12]
You could also use nested loops.
Longlistvalue:=[seq(i,i=1..14^2)]: # your values will differ, of course
B:=Array(1..14,1..14):
n:=14;
m:=14;
for j from 1 to m do
for i from 1 to n do
B[i,j]:=Longlistvalue[(j-1)*m+i];
end do;
end do:
# so we can see the contents, displayed in full
interface(rtablesize=infinity):
B;
I have a matrix in SAS/IML:
x = {7 6 3 3 8,
2 3 5 2 5,
2 6 4 3 8,
7 4 8 1 3,
8 8 6 8 7,
3 2 6 1 5 };
I want to create a new matrix that contains the highest k values of each column in x. For example, if k=3, I want the result matrix to contain:
8 8 8 8 8
7 6 6 3 8
7 6 6 3 7
because, for instance, the largest 3 numbers in the first column of x are 8, 7, and 7.
I've unsuccessfully tried to figure out how to do this using the rank function.
Your code looks fine. Here's a minor revision:
do c=1 to ncol(x);
r = rank(x[,c]);
y = x[loc(r>=nrow(x)-k+1), c];
call sort(y);
tops[,c] = y;
end;
As to avoiding the loop to make it faster, it's not necessary. Even with 10,000 columns, this code runs in a fraction of a second. Try running the following timing code:
x = j(500, 10000);
call randgen(x,"normal");
k = 3;
t0=time();
tops = j(k,ncol(x),0);
do c=1 to ncol(x);
r = rank(x[,c]);
y = x[loc(r>=nrow(x)-k+1), c];
call sort(y);
tops[,c] = y;
end;
t=time()-t0;
print t;
Here's a partial answer I've come up with:
k = 3;
tops = j(k,ncol(x),0);
do c=1 to ncol(x);
r = rank(x[,c]);
h=loc(r>=nrow(x)-k+1);
tops[,c] = x[,c][h];
end;
This approach uses a loop, which I'd like to avoid, so please post improvements if possible!
I'm trying to transpose a sparse matrix in c++. I'm struggling with the traversal of the new transposed matrix. I want to enter everything from the first row of the matrix to the first column of the new matrix.
Each row has the column index the number should be in and the number itself.
Input:
colInd num colInd num colInd num
Input:
1 1 2 2 3 3
1 4 2 5 3 6
1 7 2 8 3 9
Output:
1 1 2 4 3 7
1 2 2 5 3 8
1 3 2 6 3 9
How do I make the list traverse down the first column inserting the first element as it goes then go back to the top inserting down the second column. Apologies if this is two hard to follow. But all I want help with is traversing the Transposed matrix to be in the right place at the right time inserting a nz(non zero) object in the right place.
Here is my code
list<singleRow> tran;
//Finshed reading so transpose
for (int i = 0; i < rows.size(); i++){ // Initialize transposed matrix
singleRow trow;
tran.push_back(trow);
}
list<singleRow>::const_iterator rit;
list<singleRow>::const_iterator trowit;
int rowind;
for (rit = rows.begin(), rowind = 1; rit != rows.end(); rit++, rowind++){//rit = row iterator
singleRow row = *rit;
singleRow::const_iterator nzit;
trowit = tran.begin(); //Start at the beginning of the list of rows
trow = *trowit;
for (nzit = row.begin(); nzit != row.end(); nzit++){//nzit = non zero iterator
int col = nzit->getCol();
double val = nzit->getVal();
trow.push_back(nz(rowind,val)); //How do I attach this to tran so that it goes in the right place?
trowit++;
}
}
Your representation of the matrix is inefficient: it doesn't use the fact that the matrix is sparse. I say so because it includes all the rows of the matrix, even if most of them are zero (empty), like it usually happens with sparse matrices.
Your representation is also hard to work with. So i suggest converting the representation first (to a regular 2-D array), transposing the matrix, and convert back.
(Edited:)
Alternatively, you can change the representation, for example, like this:
Input: rowInd colInd num
1 1 1
1 2 2
1 2 3
2 1 4
2 2 5
2 3 6
3 1 7
3 2 8
3 3 9
Output:
1 1 1
2 1 2
3 1 3
1 2 4
2 2 5
3 2 6
1 3 7
2 3 8
3 3 9
The code would be something like this:
struct singleElement {int row, col; double val;};
list<singleElement> matrix_input, matrix_output;
...
// Read input matrix from file or some such
list<singleElement>::const_iterator i;
for (i = matrix_input.begin(); i != matrix_input.end(); ++i)
{
singleElement e = *i;
std::swap(e.row, e.col);
matrix_output.push_back(e);
}
Your choice of list-of-list representation for a sparse matrix is poor for transposition. Sometimes, when considering algorithms and data structures, the best thing to do is to take the hit for transforming your data structure into one better suited for your algorithm than to mangle your algorithm to work with the wrong data structure.
In this case you could, for example, read your matrix into a coordinate list representation which would be very easy to transpose, then write into whatever representation you like. If space is a challenge, then you might need to do this chunk by chunk, allocating new columns in your target representation 1 by 1 and deallocating columns in your old representation as you go.