简体   繁体   中英

Streamlining lapply function with rle in R

In R, please Consider this this sample list:

x <- c(0,0,6,25,1,3,2,8,45,27,3,45,64,170,2,47,155,153,65,131,119,57,150,50,122,105,136,112,20,162,35,12,149,18,0)
y <- c(173,30,168,3,10,34,20,172,17,165,73,53,40,141)
z <- c(2,6,3,173,15,5,13,29,14,7,33,173,8,44,112,11,165)
testList <- list(x,y,z)

I have a list of vectors and what I want to do is find the maximum amount of integers that are in a row which are > 120 and which are < 120. This would output two separate lists, one for GOOD (<120) and one for BAD (>120).

So desired output for GOOD (maximum in a row < 120) would look like:

[[1]]
 [1]  13  

[[2]]
 [1]  4

[[3]]
 [1]  7

And BAD (maximum in a row > 120) like this:

[[1]]
 [1]  2  

[[2]]
 [1]  1

[[3]]
 [1]  1

How I'm trying to solve this currently just seems very inefficient. I am setting everything that is < 120 == 1 and everything > 120 == 0. Then I'm trying to find how many zeroes are found in a row and how many ones using rle, and finally taking the max of that. I was thinking that maybe this could all be done somehow with just rle, lapply, and which. Maybe something like (it does not currently work however):

rleTest <- lapply(testList,rle) ##Use this to find out
BAD <- rleTest$lengths[rleTest$values>120]#how many of same number are in a row
GOOD <- rleTest$lengths[rleTest$values<120]
BADList <- list(max(BAD))
GOODList <- list(max(GOOD))

Two things: first, rle(x < k) will give you the lengths of both the runs less than k and the runs >= k . Second, since the output of rle is a list, you will want to find the maximum values in rle_out$lengths after sorting by rle_out$values (which will has the values 1 when x is less than k and 0 otherwise).

more like max(rle_out$lengths[rle_out$values==1]) and again with zero instead of 1 to get both the "GOOD" and "BAD".

Drop that into Matthew P's lapply and you may be all set.

Try something like this:

GOOD <- lapply(testList, function(v) with(rle(v < 120), max(lengths[values])))
# [[1]]
# [1] 13
# 
# [[2]]
# [1] 4
# 
# [[3]]
# [1] 7

BAD <- lapply(testList, function(v) with(rle(v < 120), max(lengths[!values])))

# [[1]]
# [1] 2
# 
# [[2]]
# [1] 1
# 
# [[3]]
# [1] 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM