2016-05-17 13 views
1

Ich habe einen Datenrahmen mit drei Anfangsspalten: ID, Start- und Endpositionen. Der Rest der Spalten sind numerisch chromosomal Positionen, und es sieht wie folgt aus:Wie finde ich Spalten, die zu einem bestimmten Bereich passen (pro Individuum) und addiere 1, sonst 0, mit R

ID start end 1 2 3 4 5 6 7 ... n 
ind1 2  4 
ind2 1  3 
ind3 5  7 

Was ich will, ist die leeren Spalten ausfüllen (1: n) basierend auf dem Bereich für jeden einzelnen (Start: Ende). Zum Beispiel geht in der ersten Person (ind1) der Bereich von Positionen 2 nach 4, dann werden diejenigen Positionen, die zu dem Bereich passen, mit eins (1) ausgefüllt, und diese Positionen außerhalb des Bereichs mit Null (0). Um zu vereinfachen, sollte die gewünschte Ausgabe wie folgt aussehen:

ID start end 1 2 3 4 5 6 7 ... n 
ind1 2  4 0 1 1 1 0 0 0 ... 0 
ind2 1  3 1 1 1 0 0 0 0 ... 0 
ind3 5  7 0 0 0 0 1 1 1 ... 1 

Ich werde jeden Kommentar zu schätzen wissen.

Antwort

1

Nimmt man die Anzahl der Spalten kennen Sie die between Funktion aus dem data.table Paket verwenden:

cols <- paste0('c',1:7) 

library(data.table) 
setDT(DF)[, (cols) := lapply(1:7, function(x) +(between(x, start, end)))][] 

die gibt:

 ID start end c1 c2 c3 c4 c5 c6 c7 
1: ind1  2 4 0 1 1 1 0 0 0 
2: ind2  1 3 1 1 1 0 0 0 0 
3: ind3  5 7 0 0 0 0 1 1 1 

Hinweise:

  • Es ist besser, nicht Ihre colummns mit nur Zahlen zu nennen. Daher habe ich einen c am Anfang der Spaltennamen hinzugefügt.
  • Mit + in +(between(x, start, end)) ist eine Art Tric. Der idiomatische Weg ist die Verwendung as.integer(between(x, start, end)).

Gebrauchte Daten:

DF <- read.table(text="ID start end 
ind1 2  4 
ind2 1  3 
ind3 5  7", header=TRUE) 
+0

Danke !, es funktionierte ganz gut, die einzige zusätzliche Sache war sicherzustellen, dass Start- und Endwerte mit der Reihenfolge übereinstimmen. –

1

Wenn Sie mit dem Datenrahmen df, ohne die Spalten bereits hinzugefügt,

ID start end 
1 ind1  2 4 
2 ind2  1 3 
3 ind3  5 7 

Sie

mx <- max(df[-1]) 
M <- Map(function(x, y) replace(integer(mx), x:y, 1L), df$start, df$end) 
cbind(df, do.call(rbind, M)) 
#  ID start end 1 2 3 4 5 6 7 
# 1 ind1  2 4 0 1 1 1 0 0 0 
# 2 ind2  1 3 1 1 1 0 0 0 0 
# 3 ind3  5 7 0 0 0 0 1 1 1 

Die Anzahl der neuen Spalten gleich tun könnte, beginnen waren die Maximum der start und end Spalten.

Daten:

df <- structure(list(ID = structure(1:3, .Label = c("ind1", "ind2", 
"ind3"), class = "factor"), start = c(2L, 1L, 5L), end = c(4L, 
3L, 7L)), .Names = c("ID", "start", "end"), class = "data.frame", row.names = c(NA, 
-3L)) 
+0

Schöne Basis R-Lösung! – Jaap