Ich habe eine data.frame, die 3 Spalten mit den Namen start
, end
und width
enthalten. Jede Zeile repräsentiert ein Segment über einen 1D-Raum mit einem Start und Ende und eine Breite wie die "Breite = end - start + 1"Drücken extreme Bereiche in einem dat.frame
Hier ist ein Beispiel
d = data.frame(
start = c(12, 50, 100, 130, 190),
end = c(16, 80, 102, 142, 201)
)
d$width = d$end - d$start + 1
print(d)
start end width
1 12 16 5
2 50 80 31
3 100 102 3
4 130 142 13
5 190 201 12
Betrachten sie zwei Unterbrechungspunkte und A Faktor Teilung
UpperPos = 112
LowerPos = 61
factor = 2
ich möchte die Breite jedes Segments außerhalb der beiden Haltepunkten zu reduzieren, so dass ihre Breite um einen Faktor von factor
zu reduzieren. Wenn ein Segment einen Haltepunkt überlappt, sollte nur der Teil des Segments, der außerhalb dieses Haltepunkts liegt, in der Breite reduziert werden. Außerdem muss die Breite jedes Segments ein Vielfaches von 3 sein und muss eine Länge ungleich Null haben.
Hier ist meine aktuelle Funktion, dass "squeeze" die Segmente
squeeze = function(d, factor, LowerPos, UpperPos)
{
for (row in 1:nrow(d))
{
if (d[row,]$end <= LowerPos | d[row,]$end >= UpperPos) # Complete squeeze
{
middlePos = round(d[row,]$start + d[row,]$width/2)
d[row,]$width = round(d[row,]$width/factor)
d[row,]$width = d[row,]$width - d[row,]$width %% 3 + 3
d[row,]$start = round(middlePos - d[row,]$width/2)
d[row,]$end = d[row,]$start + d[row,]$width -1
} else if (d[row,]$start <= LowerPos & d[row,]$end >= LowerPos) # Partial squeeze (Lower)
{
d[row,]$start = round(LowerPos - (LowerPos - d[row,]$start)/factor)
d[row,]$width = d[row,]$end - d[row,]$start + 1
if (d[row,]$width %% 3 != 0)
{
add = 3 - d[row,]$width %% 3
d[row,]$width = d[row,]$width + add
d[row,]$start = d[row,]$start - add
}
} else if (d[row,]$start >= UpperPos & d[row,]$end <= UpperPos) # Partial squeeze (Upper)
{
d[row,]$end = round(UpperPos + (d[row,]$end - UpperPos)/factor)
d[row,]$width = d[row,]$end - d[row,]$start + 1
if (d[row,]$width %% 3 != 0)
{
add = 3 - d[row,]$width %% 3
d[row,]$width = d[row,]$width + add
d[row,]$end = d[row,]$start + add
}
} else if (!(d[row,]$end < UpperPos & d[row,]$start > LowerPos))
{
print(d)
print(paste("row is ",row))
print(paste("LowerPos is ",LowerPos))
print(paste("UpperPos is ",UpperPos))
stop("In MyRanges_squeeze: Should not run this line!")
}
}
return(d)
}
und es gibt die erwartete Ausgabe
squeeze(d)
start end width
1 12 14 3
2 54 80 27
3 100 102 3
4 132 140 9
5 192 200 9
aber meine Funktion squeeze
ist viel zu langsam. Kannst du mir helfen, es zu verbessern?
beschleunigt es noch nicht, aber ich denke, Sie einen Fehler in Ihrem ersten 'if' Zustand. Sollte es nicht 'if (d $ end <= LowerPos | d $ start> = UpperPos) sein? Du hast zwei 'd $ end's aber die zweite sollte' d $ Start' sein? – Gregor
In der ersten Zeile wird '12, 16' zu' 12, 14' gequetscht. Warum wird nur das "Ende" aktualisiert? Warum nicht "13, 15" als Ergebnis? Vergleichen Sie mit der letzten Zeile, '190, 201 'wird auf' 192, 200' gequetscht, wo beide aktualisiert werden. – Gregor