Masi Masi - 28 days ago 13
R Question

How to adjust this data structure for smaller segments in R?

I have four complete signals in the following datastructure. I would like to split each signal to 360 blocks or close to it.
Current data structure

[1:541650, 1:4]
where four signals of the length 541650, which I want to convert to the data structure
[1:360, 1:4*1505]
or similar where I created excess spaces for the data structure because
1:4*1504
would lose some tail points

>>> 541650*4.0
2166600.0
>>> 360*1505*4
2167200.0


Current data structure, current code and its contents in R

m1 <- matrix(1:541650, ncol=4, nrow=541650); str(m1)
#int [1:541650, 1:4] 1 2 3 4 5 6 7 8 9 10 ...
#case: num [1:541650, 1:4] -0.675 -0.67 -0.67 -0.65 -0.65 -0.6 -0.555 -0.535 -0.52 -0.515 ...


Test function to the current data structure:
M.ecg.cor <- cor(M.ecg)


Current output: 4x4 matrix

Testing akrun's answer with the case example



Code

set.seed(24)
A=541650
m1 <- matrix(1:A, ncol=4, nrow=A)

a=360; b=1505; c=4;
# http://stackoverflow.com/a/40430229/54964
m2 <- array(`length<-`(m1, a*b*c), dim = c(a,b,c))

res <- apply(m2, 3, FUN = function(x) list(cor(x)))
identical(res[[1]][[1]], cor(m2[,,1]))
#[1] TRUE

res2 <- lapply(seq(dim(m2)[3]), function(i) cor(m2[,,i]))

str(res2)


Output

[1] TRUE
List of 4
$ : num [1:1505, 1:1505] 1 1 1 1 1 1 1 1 1 1 ...
$ : num [1:1505, 1:1505] 1 1 1 1 1 1 1 1 1 1 ...
$ : num [1:1505, 1:1505] 1 1 1 1 1 1 1 1 1 1 ...
$ : num [1:1505, 1:1505] 1 1 1 1 1 1 1 1 1 1 ...
# I think the tail with NAs may be sufficient.


Hmm, I am not sure about the dimensions if they are correct.

R: 3.3.1

OS: Debian 8.5

Answer

One option would be to convert to an array, but array can hold only fixed dimensions. So, if we fell short of number of elements, append some NAs at the end and then convert to a 3D array.

m2 <- array(`length<-`(m1, 30), dim = c(2,5,3)) 

and then apply the function by specifying the MARGIN as 3.

res <- apply(m2, 3, FUN = function(x) list(cor(x)))
identical(res[[1]][[1]], cor(m2[,,1]))
#[1] TRUE

Or another option is to loop through the third dimension using lapply and apply the cor

res2 <- lapply(seq(dim(m2)[3]), function(i) cor(m2[,,i]))

data

set.seed(24)
m1 <- matrix(rnorm(45), ncol=5, nrow=9)
Comments