Teste si la position x est entre les positions de début (i = 1 à i = max) et de fin (i = 1 à i = max) stockées dans les listes

Nov 28 2020

J'ai un simple bloc de données avec des positions de début et de fin dans les listes. Ces positions de début et de fin définissent un nombre de régions. Je voudrais maintenant tester si une position donnée se situe dans une telle région et si oui, j'ai besoin de savoir dans quelle région (i).

Voici un exemple de bloc de données simple:

start <- list(c(5,10,15), c(5) ,c(6,11),c(6,11))
end <- list(c(7,11,17), c(10), c(8,12),c(8,12))
imax <- c(3,1,2,2)
position <- c(11,6,9,8)

example <- data.frame(start = I(start), end = I(end), imax = imax, position = position)

Quand je n'ai qu'une seule position de début et de fin, ce n'est pas un problème (comme dans la ligne 2 de l'exemple):

data.table::between(example$position[[1]], example$start[[1]], example$end[[1]])

[1] FALSE  TRUE FALSE

Comment puis-je transformer cela en une fonction qui vérifie cela par paire pour chaque élément (de i = 1 à i = max) dans l'exemple $ start et l'exemple $ end?

La deuxième étape serait de récupérer pour quelle région i (1 à imax) c'était VRAI.

Je vous remercie.

Réponses

Ben Nov 28 2020 at 21:48

On dirait que vous cherchez peut-être une fonction comme celle-ci.

Comme vos listes startet endsont, vous pouvez unlist. Pour vérifier chaque élément par paire, vous pouvez boucler à travers startet endjusqu'à imax.

En supposant que vous puissiez avoir plus d'une région, vous pouvez renvoyer une liste (ou autre chose) à la fin de la fonction.

my_fun <- function(x) {
  vec <- integer(0)
  start <- unlist(x[["start"]])
  end <- unlist(x[["end"]])
  for (i in 1:x[["imax"]]) {
    if (between(x[["position"]], start[i], end[i])) vec <- c(vec, i)
  }
  list(vec)
}

example$regions <- apply(example, 1, my_fun)

Production

      start       end imax position regions
1 5, 10, 15 7, 11, 17    3       11       2
2         5        10    1        6       1
3     6, 11     8, 12    2        9        
4     6, 11     8, 12    2        8       1