smars - 1 year ago 77

R Question

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

Thanks in advance

[edit] 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)

[edit] 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.

Recommended for you: Get network issues from **WhatsUp Gold**. **Not end users.**

Answer Source

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**