R data.table distance from the i-th element to each remaining element in the group

Suppose I have the following data:

d = data.table( id = 1, x = c(1, 10, 17, 35, 37, 45) )

I want to see if every i-th element in x by group id is from 30 to 40 more than it. So, for the first element in x by group id (1), I am looking to find out if there is any value from x after 1 between values ​​31 and 41. The answer is yes, so I would like to create a valid_gap column that is TRUE for the first item. In the end, I'm looking for:

d_final = data.table( id = 1, x = c(1, 10, 17, 35, 37, 45), valid_gap = c(T, T, F, F, F, F ) )

I thought about this issue with a colleague for a while, and we are really trying to avoid using a loop here, but we cannot understand. Is this possible without a loop?

My best attempt is something like:

d[, valid_gap := any(between( rdist(x[ .N - .I ])[,1], left = 30, right = 40 )), by = id]

but I think of the problem as an attempt to index through x, as if in a loop, which I suspect is the wrong idea.

EDIT - "" :

x = c(1, 10, 17, 35, 37, 45)
valid_gap = c()

for( i in 1:length(x) ) {
  if( i == length(x) ){
    valid_gap = c(valid_gap, F)
  } else {
    valid_gap = c(valid_gap, any(between( rdist( x[ x >= x[i] ] )[,1], left = 30, right = 40 )) )
  }
}
valid_gap

!

+4
2

, non-equi , :

d[, v := 
  d[.(id = id, x0 = x + 30, x1 = x + 40), on=.(id, x >= x0, x <= x1), 
    .N
  , by=.EACHI][, N > 0L]
]

   id  x     v
1:  1  1  TRUE
2:  1 10  TRUE
3:  1 17 FALSE
4:  1 35 FALSE
5:  1 37 FALSE
6:  1 45 FALSE

...

  • ;
  • ( .N);
  • , 0.

mult="first".

+5
library('data.table')
myfun <- function( y, z )
{
  any( z > y+30 & z < y+40 )  # check for values between the range
}
myfun <- Vectorize( FUN = myfun, vectorize.args = 'y')  # vectorize myfun() function for 'y' argument

d = data.table( id = 1, x = c(1, 10, 17, 35, 37, 45) )
d[, valid_gap := myfun(y = x, z = x ), by = .(id)]
d
#    id  x valid_gap
# 1:  1  1      TRUE
# 2:  1 10      TRUE
# 3:  1 17     FALSE
# 4:  1 35     FALSE
# 5:  1 37     FALSE
# 6:  1 45     FALSE
+1

Source: https://habr.com/ru/post/1673552/


All Articles