Home > Software design >  extracting specific values between given start and end values R
extracting specific values between given start and end values R

Time:06-18

I have matrix M with n1 number of rows and n2 number of column,i am trying to do is extracting values where its found value greater than or equal to 0.50 and it should take all values until its found value less than 0.50. and also take 2 values before and after the starting and ending points.I am thinking to start with for loop but I am confused what I should put in condition so that It reads all line of matrix and give output.It would be great if anyone could share any idea.

Example: M:


M<- rbind(c(0.10, 0.20 ,0.40 ,0.50 ,0.49 ,0.52, 0.67, 0.58 ,0.77, 0.34, 0.31, 0.21, 0.87 ,0.65, 0.54, 0.89, 0.78, 0.50, 0.22, 0.34  
),c(0.31, 0.28, 0.74, 0.87 ,0.65, 0.54, 0.78, 0.45, 0.34, 0.41, 0.19 ,0.12 ,0.99, 0.99 ,0.89 ,0.78, 0.50, 0.66 ,0.26, 0.14))

M

  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20]
[1,] 0.10 0.20 0.40 0.50 0.49 0.52 0.67 0.58 0.77  0.34  0.31  0.21  0.87  0.65  0.54  0.89  0.78  0.50  0.22  0.34
[2,] 0.31 0.28 0.74 0.87 0.65 0.54 0.78 0.45 0.34  0.41  0.19  0.12  0.99  0.99  0.89  0.78  0.50  0.66  0.26  0.14

Desired output :

0.20 0.40 0.50 0.49 0.52 0.67 0.58 0.77 0.34 0.31
0.31 0.21 0.87 0.65 0.54 0.89 0.78 0.50 0.22 0.34   
0.31 0.28 0.74 0.87 0.65 0.54 0.78 0.50 0.34 0.41
0.19 0.12 0.99 0.99 0.89 0.78 0.54 0.66 0.26 0.14
for (i in nrows(M))
what should be the condition  here?

What I meant by occurrence : after finishing each occurrence it should be in new line,as you see the after 1st accordance 2nd one is new line

1st occurrence 0.20 0.40 0.50 0.49 0.52 0.67 0.58 0.77 0.34 0.31
2nd occurrence 0.31 0.21 0.87 0.65 0.54 0.89 0.78 0.50 0.22 0.34    
3rd occurrence 0.31 0.28 0.74 0.87 0.65 0.54 0.78 0.50 0.34 0.41
4th occurrence 0.19 0.12 0.99 0.99 0.89 0.78 0.54 0.66 0.26 0.14

CodePudding user response:

So I think I have somewhat of an answer. There is several layers to this problem as I understood it. Besides finding the consecutive occurring numbers above 0.5, there is a need to include values if they are "surrounded" by values > = 0.5, so I have also addressed that. Note that instead of looping over each row, the matrix is turned into one vector (you can also use a loop).

#Your data
M<- rbind(c(0.10, 0.20 ,0.40 ,0.50 ,0.49 ,0.52, 0.67, 0.58 ,0.77, 0.34, 0.31, 0.21, 0.87 ,0.65, 0.54, 0.89, 0.78, 0.50, 0.22, 0.34  
),c(0.31, 0.28, 0.74, 0.87 ,0.65, 0.54, 0.78, 0.45, 0.34, 0.41, 0.19 ,0.12 ,0.99, 0.99 ,0.89 ,0.78, 0.50, 0.66 ,0.26, 0.14))

#make the matrix into a single vector, with buffer zeros between rows
m <- cbind(M, rep(c(NA), nrow(M)), rep(c(NA), nrow(M)))
a <- c(t(m))

#make a coresponding binary vecto of the desired values
b <- ifelse(a >= 0.5, 1, 0)

#cumsum that restarts with zeroes
d <- ave(b, cumsum(b == 0), FUN = cumsum)

#patch the holes in desired values: 
#if one value =< 0.5, is surounded by values >= 0.5, consider this value desireble
ind1 <- c(d[-1], 0)
ind2 <- c(0, d[-length(d)])
q <- ifelse((d   ind1 > 0 & d   ind2 > 0), 1, b)

#get start and end indecies for the desired values
z <- with(rle(q), {
  ok <- values == 1 & lengths & !is.na(values) >= 1
  ends <- cumsum(lengths)
  starts <- ends - lengths   1
  data.frame(starts, ends)[ok, ]
})

## use the indecies to retrive he original values

#define a matrix to put results, using z to create corect dimensions
z$length <- z$ends - z$starts   5
res <- matrix(NA, nrow(z), ncol = max(z$length))

#forloop to go trough each line of z, creating one line for each output
for (j in 1:nrow(z)) {
  res[ j , 1:z$length[j]] <- a[(z$starts[j]-2):(z$ends[j] 2)]
}

res

PS. there is a missing value (0.5) from your data, when comparing to your desired output

  • Related