smars - 1 year ago 77
R Question

R: "Error in matrix[i, 1] : incorrect number of dimensions"

With DV and FF as vectors of length 47:

``````analyse <- function(DV,FF)
{
correct <- rep(0,47)
matrix <- array(rep(0,47*3), dim=c(47,3))

for(i in 1:47)
{
if(DV[i] > 50) {if(FF[i] > 50) {correct[i] <- i}
}
else
{
if(FF[i] < 0){correct[i] <- i}}
}

for(i in 1:47)
{
if((correct[i] == 0) == FALSE)
{
matrix[i,1] <- DV[i]
matrix[i,2] <- FF[i]
matrix[i,3] <- matrix[i,1] - matrix[i,2]
}
}

for(i in 47:1)
{
if(matrix[i,1]==0) {matrix<-matrix[-i]
}
}
return(matrix)
}
``````

I do not understand why I am getting this error:

Error in matrix[i, 1] : incorrect number of dimensions

 sample data:

DV <- c(56.2, 59.2, 50.9, 46.9, 50.7, 47.3, 53.6, 57.8, 42.7, 45.0, 47.3, 44.1, 51.5, 50.0, 50.3, 50.4, 51.7, 47.8, 46.8, 40.0, 45.5, 57.4, 51.6, 36.1, 34.8, 41.2, 59.1, 62.5, 55.0, 53.8, 52.4, 44.5, 42.2, 50.1, 61.3, 49.6, 38.2, 51.1, 44.7, 40.8, 46.1, 53.5, 54.7, 50.3, 48.8, 53.7, 52.0)

DF <- c(49.95662, 51.93295, 53.02263, 50.00784, 48.55493, 49.93520, 48.70022, 50.98856, 52.51411, 47.02938, 47.86480, 48.70022, 47.53790, 50.22578, 49.68094, 49.78991, 49.82623, 50.29842, 48.88184, 48.51861, 46.04866, 48.04641, 52.36882, 50.26210, 44.63208, 44.15988, 46.48454, 52.98631, 54.22128, 51.49707, 51.06120, 50.55268, 47.68319, 46.84776, 49.71726, 53.78541, 49.53565, 45.39485, 50.08049, 47.75583, 46.33925, 48.26435, 50.95223, 51.38811, 49.78991, 49.24506, 51.02488)

 result:

Scope of the function it to obtain a matrix which contains:
- every couple of DV[i] and FF[i] which are not both higher (or lower) than 50.
- their difference as third column.

example:

DV[1] = 55
FF[1] = 45

DV > 50 and FF < 50, so I report them in the matrix:

DV[1] -> matrix [1,1]
FF[1] -> matrix[1,2]

Third column being their difference:

matrix[1,3] <- matrix[1,1] - matrix[1,2].

With DV[2] = 55 and FF[2] = 55, analyse() does nothing because they're both higher than 50.

You can replace the final for loop with a vectorized solution:

``````analyse <- function(DV,FF)
{
correct <- rep(0,47)
matrix <- array(rep(0,47*3),dim=c(47,3))

for(i in 1:47)
{
if( DV[i] > 50 ) {
if( FF[i] > 50) {
correct[i] <- i
}
}

else {
if( FF[i] < 0) {
correct[i] <- i}
}
}

for(i in 1:47)
{
if( (correct[i] == 0) == FALSE)
{
matrix[i,1] <- DV[i]
matrix[i,2] <- FF[i]
matrix[i,3] <- matrix[i,1] - matrix[i,2]
}
}

matrix <- matrix[ matrix[,1] != 0, ]

return(matrix)
}

analyse(DV, FF)
#      [,1]     [,2]     [,3]
# [1,] 59.2 51.93295  7.26705
# [2,] 50.9 53.02263 -2.12263
# [3,] 57.8 50.98856  6.81144
# [4,] 51.6 52.36882 -0.76882
# [5,] 62.5 52.98631  9.51369
# [6,] 55.0 54.22128  0.77872
# [7,] 53.8 51.49707  2.30293
# [8,] 52.4 51.06120  1.33880
# [9,] 54.7 50.95223  3.74777
# [10,] 50.3 51.38811 -1.08811
# [11,] 52.0 51.02488  0.97512
``````

But as you mentioned, this is inefficient. There is no need for loops. The below function provides identical output.

``````analyse2 <- function(DV, FF) {
indx <- (DV > 50 & FF > 50) | FF < 0
dif <- DV[indx] - FF[indx]
matrix(c(DV[indx], FF[indx], dif), ncol=3)
}
analyse2(DV, FF)
#      [,1]     [,2]     [,3]
# [1,] 59.2 51.93295  7.26705
# [2,] 50.9 53.02263 -2.12263
# [3,] 57.8 50.98856  6.81144
# [4,] 51.6 52.36882 -0.76882
# [5,] 62.5 52.98631  9.51369
# [6,] 55.0 54.22128  0.77872
# [7,] 53.8 51.49707  2.30293
# [8,] 52.4 51.06120  1.33880
# [9,] 54.7 50.95223  3.74777
# [10,] 50.3 51.38811 -1.08811
# [11,] 52.0 51.02488  0.97512

all.equal(analyse(DV, FF), analyse2(DV, FF))
[1] TRUE
``````

edit

Based on your description, you want the values less than 50 to be reported to the matrix, not the values greater than 50 as you made in your original function. This is an edited function with an exclamation point added to the second line.

``````analyse2 <- function(DV, FF) {
indx <- (!DV > 50 & FF > 50) | FF < 0
dif <- DV[indx] - FF[indx]
matrix(c(DV[indx], FF[indx], dif), ncol=3)
}

analyse2(DV, FF)
#      [,1]     [,2]      [,3]
# [1,] 46.9 50.00784  -3.10784
# [2,] 42.7 52.51411  -9.81411
# [3,] 50.0 50.22578  -0.22578
# [4,] 47.8 50.29842  -2.49842
# [5,] 36.1 50.26210 -14.16210
# [6,] 44.5 50.55268  -6.05268
# [7,] 49.6 53.78541  -4.18541
# [8,] 44.7 50.08049  -5.38049
``````

edit 2

With either both greater or lesser than 50.

``````analyse3 <- function(DV, FF) {
indx <- !( (DV > 50 & FF > 50) | (DV < 50 & FF < 50) )
dif <- DV[indx] - FF[indx]
matrix(c(DV[indx], FF[indx], dif), ncol=3)
}
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download