R shortcut to getting last n entries in a vector [duplicate] - arrays

This question already has answers here:
How to access the last value in a vector?
(12 answers)
Closed 10 years ago.
This may be redundant but I could not find a similar question on SO.
Is there a shortcut to getting the last n elements/entries in a vector or array without using the length of the vector in the calculation?
foo <- 1:23
> foo
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
Let say one wants the last 7 entities, I want to avoid this cumbersome syntax:
> foo[(length(foo)-6):length(foo)]
[1] 17 18 19 20 21 22 23
Python has foo[-7:]. Is there something similar in R? Thanks!

You want the tail function
foo <- 1:23
tail(foo, 5)
#[1] 19 20 21 22 23
tail(foo, 7)
#[1] 17 18 19 20 21 22 23
x <- 1:3
# If you ask for more than is currently in the vector it just
# returns the vector itself.
tail(x, 5)
#[1] 1 2 3
Along with head there are easy ways to grab everything except the last/first n elements of a vector as well.
x <- 1:10
# Grab everything except the first element
tail(x, -1)
#[1] 2 3 4 5 6 7 8 9 10
# Grab everything except the last element
head(x, -1)
#[1] 1 2 3 4 5 6 7 8 9

Not a good idea when you have the awesome tail function but here's an alternative:
n <- 3
rev(rev(foo)[1:n])
I'm preparing myself for the down votes.

Related

Stat2Data package doesn't allow me to use the objects in it

Stat2Data package contains a lot of exemplary datasets. I get no errors when installing it or using the library function to call it. However, it doesn't allow me to work with the objects.
Anyone familiar with this package and know what I can do about it? Here's the code that I used:
install.packages("Stat2Data")
library(Stat2Data)
# Attempt 1
MedGPA_ds <- ggplot(MedGPA, aes(x = GPA, y = Acceptance))
# Attempt 2
MedGPA_ds <- ggplot(Stat2Data::MedGPA, aes(x = GPA, y = Acceptance))
You have missed just one step, the use of the data() function to call the specific dataset (MedGPA) contained within the Stat2Data package.
Try the following:
library(Stat2Data)
data(MedGPA)
head(MedGPA)
Accept Acceptance Sex BCPM GPA VR PS WS BS MCAT Apps
1 D 0 F 3.59 3.62 11 9 9 9 38 5
2 A 1 M 3.75 3.84 12 13 8 12 45 3
3 A 1 F 3.24 3.23 9 10 5 9 33 19
4 A 1 F 3.74 3.69 12 11 7 10 40 5
5 A 1 F 3.53 3.38 9 11 4 11 35 11
6 A 1 M 3.59 3.72 10 9 7 10 36 5
Happy coding!

How to perform transpose to each page of nd array? [duplicate]

This question already has an answer here:
Matlab - Transpose a 3D matrix only in the third dimension
(1 answer)
Closed 5 years ago.
I am trying to figure out how to import large array of data into 3D matrix to a specific order. I have already asked two question but i have not get reliable answer yet and get down voted too. Since then i have done some work and was able to import data to 3D matrix using reshape function. Instead of shooting actual problem, this is a simulation of actual problem.
k=1:27 % create a array of 27 data
r=reshape(k,[3,3,3]) % convert the array into 3 x 3 x 3 matrix,
The results of the first page and second of the matrix is, the data is placed along the columns, but i wanted to place them along rows, The transpose function does not work with ND arrays, I tried to use permute but i did not get the desired result, One solution will be perform transpose to each page, but that will break the 3D matrix in to many 2D matrices.
r(:,:,1) =
1 4 7
2 5 8
3 6 9
r(:,:,2) =
10 13 16
11 14 17
12 15 18
the expected outcome should be,
r(:,:,1) =
1 2 3
4 5 6
7 8 9
Link to the actual problem is,
Thanks
Is this what you want?
result = permute(r, [2 1 3]);
This permutes the first two dimensions. For your example r,
>> k = 1:27;
>> r = reshape(k, [3,3,3]);
>> result = permute(r, [2 1 3]);
>> result
result(:,:,1) =
1 2 3
4 5 6
7 8 9
result(:,:,2) =
10 11 12
13 14 15
16 17 18
result(:,:,3) =
19 20 21
22 23 24
25 26 27

2D MATRIX statement for 5 x 5 Grid

Given a 5 x 5 Grid comprising of tiles numbered from 1 to 25 and a set of 5 start-end point pairs.
For each pair,find a path from the start point to the end point.
The paths should meet the below conditions:
a) Only Horizontal and Vertical moves allowed.
b) No two paths should overlap.
c) Paths should cover the entire grid
Input consist of 5 lines.
Each line contains two space-separated integers,Starting and Ending point.
Output: Print 5 lines. Each line consisting of space-separated integers,the path for the corresponding start-end pair. Assume that such a path Always exists. In case of Multiple Solution,print any one of them.
Sample Input
1 22
4 17
5 18
9 13
20 23
Sample Output
1 6 11 16 21 22
4 3 2 7 12 17
5 10 15 14 19 18
9 8 13
20 25 24 23
i think there should be restriction or it lacks some more information about the input ( start point and endpoint)
because if we take following input then covering whole grid is not possible
1 22,
6 7,
11 12,
16 17,
8 9

What is the meaning of the addition at the end of this array declaration?

I'm tasked with implementing an algorithm which was supplied as Matlab (which none of us have any experience with) into our c++ application.
There is an array declared as such:
encrypted = [18 10 20 13 6 25 21 13 17;
2 26 4 29 22 9 5 29 1;
19 11 21 12 7 24 20 12 16;
% ... many rows like this ...
13 21 11 18 25 6 10 18 14]+1;
What is the semantic meaning of the +1 at the end of the array declaration?
Simply adding 1 to each entry:
>> [1 2 3; 4 5 6]
ans =
1 2 3
4 5 6
>> [1 2 3; 4 5 6] + 1
ans =
2 3 4
5 6 7
If you have MATLAB around, you could have figured that out by just trying. If you do not, I hope you have a very clear picture of what the code is doing and write a good test suite, since you won't be able to compare your new code's output to the MATLAB one.
The +1 means that all elements of the written matrix will be increased by one.
Example
out = [1 2;
3 4] + 1;
disp(out)
2 3
4 5

Rearranging an array using for loop in Matlab

I have a 1 x 15 array of values:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
I need to rearrange them into a 3 x 5 matrix using a for loop:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
How would I do that?
I'm going to show you three methods. One where you need to have a for loop, and two others when you don't:
Method #1 - for loop
First, create a matrix that is 3 x 5, then keep track of an index that will go through your array. After, create a double for loop that will help you populate the array.
index = 1;
array = 1 : 15; %// Array we wish to access
matrix = zeros(3,5); %// Initialize
for m = 1 : 3
for n = 1 : 5
matrix(m,n) = array(index);
index = index + 1;
end
end
matrix =
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
Method #2 - Without a for loop
Simply put, use reshape:
matrix = reshape(1:15, 5, 3).';
matrix =
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
reshape will take a vector and restructure it into a matrix so that you populate the matrix by columns first. As such, we want to put 1 to 5 in the first column, 6 to 10 in the second and 11 to 15 in the third column. Therefore, our output matrix is in fact 5 x 3. When you see this, this is actually the transposed version of the matrix we want, which is why you do .' to transpose the matrix back.
Method #3 - Another method without a for loop (tip of the hat goes to Luis Mendo)
You can use vec2mat, and specify that you need to have 5 columns worth for your matrix:
matrix = vec2mat(1:15, 5);
matrix =
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
vec2mat takes a vector and reshapes it into a matrix of as many columns as you specify in the second parameter. In this case, we need 5 columns.
For the sake of (bsx)fun, here is another option...
bsxfun(#plus,1:5,[0:5:10]')
ans =
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
less readable, maybe faster, but who cares if it is such a small of an array...
A = [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ] ;
A = reshape( A' , 3 , 5 ) ;
A' = 1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

Resources