Testen Sie, ob die Position x zwischen einer in Listen gespeicherten Start- (i = 1 bis i = max) und Endposition (i = 1 bis i = max) liegt

Nov 28 2020

Ich habe einen einfachen Datenrahmen mit festgelegten Start- und Endpositionen innerhalb von Listen. Diese Start- und Endpositionen definieren eine Anzahl von Regionen. Jetzt möchte ich testen, ob eine bestimmte Position in einer solchen Region liegt und wenn ja, muss ich wissen, in welcher Region (i).

Hier ist ein einfacher Beispieldatenrahmen:

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)

Wenn ich nur eine Start- und Endposition habe, ist das kein Problem (wie in Zeile 2 des Beispiels):

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

[1] FALSE  TRUE FALSE

Wie kann ich daraus eine Funktion machen, die dies paarweise für jedes Element (von i = 1 bis i = max) in Beispiel $ start und Beispiel $ end überprüft?

Der zweite Schritt wäre, abzurufen, für welche Region i (1 zu imax) dies WAHR war.

Vielen Dank.

Antworten

Ben Nov 28 2020 at 21:48

Es hört sich so an, als würden Sie nach einer solchen Funktion suchen.

Als Ihre startund endsind Listen, können Sie unlist. Um jedes Element paarweise zu überprüfen, können Sie eine Schleife durch startund endbis zu durchlaufen imax.

Angenommen, Sie können mehr als eine Region haben, können Sie am Ende der Funktion eine Liste (oder etwas anderes) zurückgeben.

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)

Ausgabe

      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