0

Basically I have a 4 dimensional array of various radar variables named pol which has dim (5,1191,360,11)

For part of my analysis I want to subset the analysis to only those pixels below a certain height, note pol[2,,,] contains the height information ideally I would like to do something like this

Newpol<-pol[pol[2,,,]<5,]

the issue is this construct is not for four dimensional features, I have tried

Newpol[,,,]<-pol[,,,][pol[2,,,]<5,,,]

but this results in the error "Logical subscript too long"

My goal is to obtain a four dimensional array only consisting of the elements of pol where pol[2,,,]<5.

Thanks in advance for your assistance.

r2evans
  • 141,215
  • 6
  • 77
  • 149
  • It may be better to provide a small reproducible example http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – akrun Apr 01 '15 at 16:25
  • I am not sure whether I get it right, but do you want to filter your data by the values of four columns? If that is the case, try `Newpol <- df[pol>2 & height >3 & note >5 & sth >4,]` – rmuc8 Apr 01 '15 at 16:38

1 Answers1

2

Two things will help here: adding ,drop=FALSE to your indexing, and which(..., arr.ind=TRUE).

Some data:

set.seed(42)
pol <- array(sample(20, size=3*4*5*6, replace=TRUE), dim=c(3,4,5,6))

This is the simple subsetting, but you lose dimensionality from the c(3,4,5,6) to c(4,5,6), not good:

pol[2,,,] < 5
## , , 1
##       [,1]  [,2]  [,3]  [,4]  [,5]
## [1,] FALSE FALSE FALSE FALSE FALSE
## [2,] FALSE FALSE FALSE FALSE FALSE
## [3,]  TRUE FALSE FALSE FALSE FALSE
## [4,] FALSE FALSE  TRUE FALSE FALSE
## , , 2
## ...snip...

To fix this, use drop=FALSE:

pol[2,,,,drop=FALSE] < 5
## , , 1, 1
##       [,1]  [,2] [,3]  [,4]
## [1,] FALSE FALSE TRUE FALSE
## , , 2, 1
##       [,1]  [,2]  [,3]  [,4]
## [1,] FALSE FALSE FALSE FALSE
## , , 3, 1
## ...snip...

A nice trick is to get the indices of all of the "successes" using:

head(which(pol[2,,,,drop=FALSE] < 5, arr.ind=TRUE))
##      dim1 dim2 dim3 dim4
## [1,]    1    3    1    1
## [2,]    1    4    3    1
## [3,]    1    4    1    2
## [4,]    1    2    2    2
## [5,]    1    3    2    2
## [6,]    1    2    3    2

to which you can easily get the individual values:

pol[ which(pol[2,,,,drop=FALSE] < 5, arr.ind=TRUE) ]
##  [1] 15 14  5 15 11  2 14 11  4 13  3  9  6  3  4 16 11  7  7 13  8  7 10  8 19
## [26] 12

Hope this helps.

r2evans
  • 141,215
  • 6
  • 77
  • 149