Home > OS >  Remove list element where any of the row sums in the element are less than a certain value (in R)
Remove list element where any of the row sums in the element are less than a certain value (in R)

Time:05-10

Apologies in advance for what I know is simple. I just haven't been able to find the solution despite the 1000 search attempts and my rudimentary skills are not up to the challenge.

I have a list of matrices consisting of rows of integers. I can find row totals etc with (l)apply function etc. What I am stuck on however is removing an entire element if any of the rows fail a certain criteria, say a total of <500.

So in the below example:

x1 <- rnorm(50,5,0.32)
dim(x1) <- c(5,10)
x2 =rnorm(50,25,3.2)
dim(x2) <- c(5,10)
x3 =rnorm(50,25,3.2)
dim(x3) <- c(5,10)
x4=rnorm(50,0.8,0.1)
dim(x4) <- c(5,10)
x5=rep(NaN,50)
dim(x5) <- c(5,10)

list1<-list(x1,x2,x3,x4,x5)

If I sum each row in each element for a total:

goodbit <- lapply(list1, function (x) apply(x, 1, function(c) sum(c)))

I know I can filter out the elements with NAs:

list1nonas  <- Filter(Negate(anyNA),list1)

But I am having a hard time extending that to criteria based on the row totals. For example how can I remove any element where any row total in that element is < 8. (Element [[4]] in this example).

CodePudding user response:

You can use rowSums. If we want to test whether there are any rowSums less than 8 in a given matrix x, we can do any(rowSums(x) < 8). Therefore the logical negation negation of this will return TRUE if none of the row sums are less than 8.

We can therefore put this inside an sapply to run the test on each matrix in our list, and return a logical vector.

Subsetting our original list by this vector returns a filtered list with only those matrices that have no row sums below 8.

list1[sapply(list1, function(x) !any(rowSums(x) < 8))]
  • Related