transform - Assigning a value to each range of consecutive numbers with same sign in R -


i'm trying create data frame column exists holds values representing length of runs of positive , negative numbers, so:

time  v  length 0.5  -2  1.5 1.0  -1  1.5 1.5   0  0.0 2.0   2  1.0 2.5   0  0.0 3.0   1  1.75 3.5   2  1.75 4.0   1  1.75 4.5  -1  0.75 5.0  -3  0.75 

the length column sums length of time value has been positive or negative. zeros given 0 since inflection point. if there no 0 separating sign change, values averaged on either side of inflection.

i trying approximate amount of time these values spending either positive or negative. i've tried for loop varying degrees of success, avoid looping because working extremely large data sets.

i've spent time looking @ sign , diff used in this question sign changes. i've looked @ this question uses transform , aggregate sum consecutive duplicate values. feel use in combination sign and/or diff, i'm not sure how retroactively assign these sums ranges created them or how deal spots i'm taking average across inflection.

any suggestions appreciated. here sample dataset:

dat <- data.frame(time = seq(0.5, 5, 0.5), v = c(-2, -1, 0, 2, 0, 1, 2, 1, -1, -3)) 

first find indices of "time" need interpolated: consecutive "v" lack 0 between positive , negative values; have abs(diff(sign(v)) equal two.

id <- which(abs(c(0, diff(sign(dat$v)))) == 2) 

add rows average "time" between relevant indices , corresponding "v" values of 0 original data. add rows of "v" = 0 @ "time" = 0 , @ last time step (according assumptions mentioned @gregor). order "time".

d2 <- rbind(dat,             data.frame(time = (dat$time[id] + dat$time[id - 1])/2, v = 0),             data.frame(time = c(0, max(dat$time)), v = c(0, 0))             ) d2 <- d2[order(d2$time), ] 

calculate time differences between time steps 0 , replicate them using "zero-group indices".

d2$length <- diff(d2$time[d2$v == 0])[cumsum(d2$v == 0)] 

add values original data:

merge(dat, d2)  #    time  v length # 1   0.5 -2   1.50 # 2   1.0 -1   1.50 # 3   1.5  0   1.00 # 4   2.0  2   1.00 # 5   2.5  0   1.75 # 6   3.0  1   1.75 # 7   3.5  2   1.75 # 8   4.0  1   1.75 # 9   4.5 -1   0.75 # 10  5.0 -3   0.75 

set "length" 0 v == 0.


Comments

Popular posts from this blog

sql server - Cannot query correctly (MSSQL - PHP - JSON) -

php - trouble displaying mysqli database results in correct order -

C++ Linked List -