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

# https://stackoverflow.com/q/40429343/54964
library("corrgram")

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

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

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

res2 <- lapply(res, function(x) eigen(replace(x, is.na(x), 0))$vectors[,1:2])
str(res2)

res2 <- do.call(rbind, res2) # a single matrix
dim(res2) # 6020 2

# Not Passed because output strange
corrgram(res2,
  upper.panel=panel.pie,
  lower.panel=panel.shade,
  text.panel=panel.txt,
  order=NULL,
  diag.panel=panel.minmax)

Output, Fig. 1 Output is only 1x1 matrix

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 ...
List of 4
 $ : num [1:1505, 1:2] -0.0258 -0.0258 -0.0258 -0.0258 -0.0258 ...
 $ : num [1:1505, 1:2] -0.0258 -0.0258 -0.0258 -0.0258 -0.0258 ...
 $ : num [1:1505, 1:2] -0.0258 -0.0258 -0.0258 -0.0258 -0.0258 ...
 $ : num [1:1505, 1:2] -0.0258 -0.0258 -0.0258 -0.0258 -0.0258 ...
[1] 6020    2

enter image description here

Expected output: 6020x6020 matrix

R: 3.3.1
OS: Debian 8.5

Upvotes: 1

Views: 57

Answers (1)

akrun
akrun

Reputation: 887158

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)

Upvotes: 1

Related Questions