Three-dimensional array in R for netCDF - arrays

I need to create a three-dimensional array in R which contains the data of a raster with a resolution of 538x907 pixel. I have this raster for each hour in one month, so in January there are 744 raster files. I have to change some values by R and want to summarize them afterwards back to an array that can be processed by the package ncdf4. Therefor I need to create a three-dimensional array which looks like prectdata[1:538, 1:907, 1:744] (first and second for x and y dimension of the raster, third for time dimension). How do I have do concatenate the 744 raster matrices to a three-dimensioanl array for Package ncdf4?

The raster package has a function called as.array which should do just what you want:
library(raster)
# single raster
r <- raster(matrix(runif(538*907),nrow =538))
# stack them
rstack <- do.call(stack,lapply(1:744,function(x) r))
# structure
> rstack
class : RasterStack
dimensions : 538, 907, 487966, 744 (nrow, ncol, ncell, nlayers)
resolution : 0.001102536, 0.001858736 (x, y)
extent : 0, 1, 0, 1 (xmin, xmax, ymin, ymax)
coord. ref. : NA
# convert to array
arr <- as.array(rstack)
# check dimensions
> dim(arr)
[1] 538 907 744

Related

How do I plot these values against each other?

So I have a .csv file which has 3 value-types: Time, Torque and Angle.
The values are saved in seperate columns like that:
Row 1: Time1, Torque1, Angle1, ..., TimeX,TorqueX,AngleX.
The rest of the rows are the Values (745 Values each Instance and Variable)
So first I transposed the DataFrame and seperated it into the different variables.
time=df_trans.iloc[::3, :]
torque=df_trans.iloc[1: : 3, :]
angle=df_trans.iloc[2 : :3,:]
So now I have DataFrames with the Times, Torques and Angles of the X instances. (In this example 5 instances) Each Instance having a row and the columns being the values of the Instance.
For example print(angle):
0 ... 745
01.01.1990 01:33:51 Angle 0 ... 5225,68408203125
01.01.1990 01:35:09 Angle 0 ... 5186,560546875
01.01.1990 01:35:58 Angle 0 ... 3794,25634765625
01.01.1990 01:37:11 Angle 0 ... 3230,36791992188
01.01.1990 01:37:57 Angle 0 ... 3794,13012695313
[5 rows x 746 columns]
Now I want to plot the angles against the torque of the Instance for all instances in one plot, but I can't seem to get it working.
The code:
df = pd.read_csv("Kurven.csv", sep=';', header=[0])
df_trans=df.transpose()
time=df_trans.iloc[::3, :]
time
torque=df_trans.iloc[1: : 3, :]
torque
angle=df_trans.iloc[2::3,:]
angle
Then I tried plotting:
import matplotlib.pyplot as plt
plt.plot(angle,torque)
got this Error:
TypeError: unhashable type: 'numpy.ndarray'
Then I tried:
import matplotlib.pyplot as plt
for i, j in angle,torque:
plt.plot(i,j)
Got this Error:
ValueError: too many values to unpack (expected 2)

How to I calculate the correlation coefficient of matrices inside an array?

I have an relatively large array (242x240x2922). The first two dimensions are latitude and longitude, and the third dimension is time (daily satellite images).
I need to extract the correlation coefficient for a subset of that array that corresponds to data within a 6° Radius of each one of the (lon, lat) pairs. First, I created a loop that calculates the circle polygon for each of the lon, lat pairs. Then, I checked which points are inside the circle (with the point.in.polygon function), and extracted the subset of the larger array.
I know I could build a second, nested loop that can calculate the correlation of the time series of each lon, lat with the rest of the time series of the "sub array" (those that fall within the circle), but It would take too long... is there any straight forward way to calculate the correlation coefficient of a vector of size "L" with each of the vectors of an array that has NxMxL dimensions? For example, in a loop, the first round would calculate cor(myvector, myarray[,,1]).
I tried using apply(myarray, dim=3, cor), but I'm struggling to understand the results.
Thanks a lot in advance.
#define dimensions
M = 3; N = 4; L = 5
myarray <- array(data = rnorm(M*N*L), dim=c(M,N,L))
myvector <- myarray[1,1, ]
# Use apply function to cycle through all the vectors in 3rd dimension:
result <- apply(myarray, c(1,2), FUN=function(x)cor(myvector,x))
result
# [,1] [,2] [,3] [,4]
#[1,] 1.00000000 0.73804476 0.7356366 -0.1583484
#[2,] 0.03820936 -0.07797187 0.3798744 -0.4925700
#[3,] -0.52827708 -0.09036006 0.1895361 -0.2860481
# For testing compare with the loop result (which will be much slower for larger arrays):
for (i in 1:dim(myarray)[1])
for (j in 1:dim(myarray)[2])
print( cor(myvector,myarray[i,j,]))
# [1] 1
# [1] 0.7380448
# [1] 0.7356366
# [1] -0.1583484
# [1] 0.03820936
# [1] -0.07797187
# [1] 0.3798744
# [1] -0.49257
# [1] -0.5282771
# [1] -0.09036006
# [1] 0.1895361
# [1] -0.2860481

Subsetting multi-dim. array with matrices

i want to subset a 3-dimensional array with three matrices where each matrix represents one dimension.
An example:
set.seed(1)
A = array(sample(1:10,24, replace=TRUE), dim=c(3,4,2))
ind_dimension1 = matrix(c(1,3,2,1), nrow=2)
ind_dimension2 = matrix(c(4,3,2,1), nrow=2)
ind_dimension3 = matrix(c(1,2,2,1), nrow=2)
As result i want a matrix with the same dimension as the subsetting matrices, i.e. 2x2:
# A[1,4,1](=1) A[2,2,2](=8)
# A[3,3,2](=10) A[1,1,1](=3)
In Matlab this can be done by:
A(sub2ind(size(A), ind_dimension1, ind_dimension2, ind_dimension3))
With two dimensions, i.e. A2=A[,,1], the Matlab command sub2ind(size(A2), ind_dimension1, ind_dimension2) can be replicated in R with (ind_dimension2-1)*dim(A2)[2]+ind_dimension1 as mentioned by Hiebeler (2010) https://cran.r-project.org/doc/contrib/Hiebeler-matlabR.pdf (Page 5). This is not possible in higher dimensions.
Thanks in advance.
How about this?
myMat <- matrix(A[cbind(c(ind_dimension1),
c(ind_dimension2),
c(ind_dimension3))],
dim(ind_dimension1))
myMat
[,1] [,2]
[1,] 1 8
[2,] 10 3
This uses matrix subsetting (see help("[")) to extract the desired elements. The dimension matrices are turned into vectors with c, and then recombined into a matrix with cbind that is used to extract from the array. The resulting vector is fed to matrix and the desired dimensions are produces with dim.

What are the differences between vector, matrix and array data types?

R comes with three types to store lists of homogenous objects: vector, matrix and array.
As far as I can tell:
vector is special cases for 1 dimension arrays
matrix is a special case for 2 dimensions arrays
array can also have any dimension level (including 1 and 2).
What is the difference between using 1D arrays over vectors and 2D arrays over matrices? Do we need to cast between those, or will it happen automagically?
There is no difference between a matrix and a 2D array:
> x <- matrix(1:10, 2)
> y <- array(1:10, c(2, 5))
> identical(x, y)
[1] TRUE
...
matrix is just a more convenient constructor, and there are many functions and methods that only accept 2D arrays (a.k.a. matrices).
Internally, arrays are just vectors with a dimension attribute:
...
> attributes(x)
$dim
[1] 2 5
> dim(x) <- NULL
> x
[1] 1 2 3 4 5 6 7 8 9 10
> z <- 1:10
> dim(z) <- c(2, 5)
> is.matrix(z)
[1] TRUE
To cite the language definition:
Matrices and arrays are simply vectors with the attribute dim and
optionally dimnames attached to the vector.
[...]
The dim attribute is used to implement arrays. The content of the
array is stored in a vector in column-major order and the dim
attribute is a vector of integers specifying the respective extents of
the array. R ensures that the length of the vector is the product of
the lengths of the dimensions. The length of one or more dimensions
may be zero.
A vector is not the same as a one-dimensional array since the latter
has a dim attribute of length one, whereas the former has no dim
attribute.

multiply each matrix slice in a 3d array by a single matrix in R

Suppose I have a 1 x matrix mat=matrix(1,1,13)
I also have an array that is 13 x 1000 x 10.
dfarray = array(1:(13*1000*10),dim=c(13,1000,10))
Without looping, I want to return the results of this loop
dfarray2=array(NA,dim=c(1,1000,10))
for(i in 1:10){
dfarray2[,,i]=mat%*%dfarray[,,i]
}
One possibility: deform the dfarray to usual matrix, multiply and transform back to 3d array.
mat <- matrix(1, 1, 13)
dim(dfarray) <- c(13, 1000*10)
dfarray1 <- mat %*% dfarray
dim(dfarray1) <- c(1, 1000, 10)
all(dfarray1==dfarray2)
[1] TRUE

Resources