Elegant Indexing Up to End of Vector/Matrix

Elegant indexing up to end of vector/matrix

Sometimes it's easier to tell R what you don't want. In other words, exclude columns from the matrix using negative indexing:

Here are two alternative ways that both produce the same results:

A[, -(1:2)]
A[, -seq_len(2)]

Results:

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 4 5 6 7 8
[2,] 3 4 5 6 7 8
[3,] 3 4 5 6 7 8
[4,] 3 4 5 6 7 8
[5,] 3 4 5 6 7 8

But to answer your question as asked: Use ncol to find the number of columns. (Similarly there is nrow to find the number of rows.)

A[, 3:ncol(A)]

[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 4 5 6 7 8
[2,] 3 4 5 6 7 8
[3,] 3 4 5 6 7 8
[4,] 3 4 5 6 7 8
[5,] 3 4 5 6 7 8

let indexing return a matrix instead of a vector in julia

Just use 1:1 (range) instead of 1, e.g.:

julia> A[:, 1:1]
2×1 Matrix{Int64}:
1
3

julia> A[1:1, :]
1×2 Matrix{Int64}:
1 2

julia> A[1:1, 1:1]
1×1 Matrix{Int64}:
1

You could also use [1] instead, but it will allocate, while 1:1 does not allocate.

Extracting a vector from a matrix using vector of column indices

You have the column subscripts. Generate the row subscripts and use sub2ind to get linear indices to retrieve desired elements of A.

B = A(sub2ind(size(A),1:numel(v),v))

Matrix index from vector

Convert v to a cell-array (say cellv) using num2cell and then extract elements of cellv as comma separated values to index A and implement A(v(1), v(2), v(3), v(4), ... v(n)) in a generalised manner.

cellv = num2cell(v);
A(v{:})

Convert a matrix of indices from a vector of values

You can simply index c with B:

B2 = c(B);

Indexing a matrix by a vector

You can use cbind() to create a matrix to be used for indexing.

m[cbind(seq_along(y), y)]
# [1] 1 7 8 4 5

R: matrix to indexes

Here's an answer using IRanges package:

require(IRanges)
xx.ir <- IRanges(start = xx[,1], end = xx[,2])
as.vector(coverage(xx.ir))
# [1] 1 1 1 1 1 1 0 0 0 0 1 1 1 1

If you specify a min and max value of your entire vector length, then:

max.val <- 20
min.val <- 1
c(rep(0, min.val-1), as.vector(coverage(xx.ir)), rep(0, max.val-max(xx)))

Logical indexing of matrix returning vector - need for initialization?

You can use accumarray to rescue yourself here, but you still need to pre-allocate for the output, which is okay I hope as you are going to use that output anyway otherwise you won't need it in the first place. For your problem case, you can use two appproaches here.

Approach #1

[~,c] = find(ind); %// get column indices
out = NaN(1,size(Data,2)); %// pre-allocate for output

calc_result = accumarray(c,Data(ind),[], @mean) %// get mean calculated results
array1 = 1:max(c)
vind = ismember(array1,c) %// valid indices
out(array1(vind)) = calc_result(vind)

Approach #2

[~,c] = find(ind); %// get column indices OR try c = ceil(find(ind)/size(ind,1))
vind = c(diff([0 ; c])~=0); %// valid indices

out(1,1:size(Data,2)) = NaN; %// pre-allocate for output
calc_result = accumarray(c,Data(ind),[], @mean); %// get mean calculated results
out(vind) = calc_result(vind);

Complete code for comparison with the trusted output y1 with approach #1 -

clear all; close all; clc;

% Initialization
x1 = NaN * ones(3,4);
y1 = NaN * ones(1,4);
y2 = y1;

Data = [
1 2 3 4;
3 4 5 6;
5 6 7 8]

% Indices of data to be averaged over rows:
ind = logical([0 0 0 0;0 1 0 0;0 1 0 1])

x1(ind) = Data(ind); % writing to pre-allocated NaN matrix (necessary?)
y1(1:4) = nanmean(x1,1) % take NaN-mean - good result

[~,c] = find(ind); %// get column indices
out = NaN(1,size(Data,2)); %// pre-allocate for output

calc_result = accumarray(c,Data(ind),[], @mean);
array1 = 1:max(c);
vind = ismember(array1,c);
out(array1(vind)) = calc_result(vind)

Output -

Data =
1 2 3 4
3 4 5 6
5 6 7 8
ind =
0 0 0 0
0 1 0 0
0 1 0 1
y1 =
NaN 5 NaN 8
out =
NaN 5 NaN 8


Related Topics



Leave a reply



Submit