R: Использование функции сегментов для построения карты сложенных линий - PullRequest
1 голос
/ 07 марта 2012

Я написал функцию, которая строит несколько линий вдоль оси, укладывая их там, где они перекрываются. Ниже приведен код, пример таблицы и изображение, которое он создает.

Сюжет в основном именно то, что я искал, но для нескольких вещей (в порядке важности):

  1. Построение сегментов является чрезвычайно медленным процессом: около 1 сегмента каждые 0,5 секунды. Учитывая, что это всего лишь линии, я ожидал чего-то гораздо более быстрого. Я не знаю причину этого. Я знаю, что явные циклы могут быть медленными в R, так что это может быть так, или я должен как-то рисовать за кадром, а потом выводить график на экран? Очень важно найти эффективный по времени метод для построения карт такого типа, потому что мои таблицы легко могут быть длиной в десятки тысяч строк.

  2. Я не могу найти способ указать зазор между позициями y на фиксированном расстоянии независимо от количества позиций Y. В крайнем случае, построение только двух сегментов дает график с сегментами, расположенными очень далеко друг от друга.

Может ли кто-нибудь помочь мне с любым из этих пунктов (или, действительно, чем-то еще, что я мог бы сделать лучше)?

(в этом коде читается == сегменты)

Функция:

viewReads <- function(reads){
    # sort by start
    sorted <- reads[order(reads$start),];

    #---
    # In the first iteration we work out the y-axis
    # positions that segments should be plotted on
    # segments should be plotted on the next availible
    # y position without merging with another segment
    #---
    yread <- c(); #keeps track of the x space that is used up by segments 

    # get x axis limits
    minstart <- min(sorted$start);
    maxend <- max(sorted$end);

    # initialise yread
    yread[1] <- minstart - 1;
    ypos <- c(); #holds the y pos of the ith segment

    # for each read
    for (r in 1:nrow(sorted)){
        read <- sorted[r,];
        start <- read$start;
        placed <- FALSE;

        # iterate through yread to find the next availible
        # y pos at this x pos (start)
        y <- 1;
        while(!placed){

            if(yread[y] < start){
                ypos[r] <- y;
                yread[y] <- read$end;
                placed <- TRUE;
            } 

            # current y pos is used by another segment, increment
            y <- y + 1;
            # initialize another y pos if we're at the end of the list
            if(y > length(yread)){
                yread[y] <- minstart-1;
            }
        }
    } 

    # find the maximum y pos that is used to size up the plot
    maxy <- length(yread);
    sorted$ypos <- ypos;

    # Now we have all the information, start the plot
    plot.new();
    plot.window(xlim=c(minstart, maxend+((maxend-minstart)/10)), ylim=c(1,maxy));
    axis(3);

    #---
    # This second iteration plots the segments using the found y pos and 
    # the start and end values
    #---
    for (r in 1:nrow(sorted)){
        read <- sorted[r,];
        # colour dependent on strand type
        if(read$strand == '+'){
            color = 'blue'
         }else{
            color = 'red'
         } 
        #plot this segment!
        segments(read$start, maxy-read$ypos, read$end, maxy-read$ypos, col=color);
    }
}

Пример кода:

start   end strand
86  115 +
87  115 +
91  116 +
88  117 +
91  117 +
98  125 -
104 131 +
104 131 +
106 132 -
104 134 +
104 134 +
104 134 +
106 134 +
106 134 +
106 134 +
106 134 +
106 134 +
106 135 +
106 135 +
106 135 +
106 135 +
106 135 +
106 135 +
106 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
108 135 +
109 135 +
116 135 -
106 136 +
106 136 +
106 136 +
108 136 +
108 136 +
108 136 +
108 136 +
108 136 +
108 136 +
108 136 +
108 136 +
108 136 +
108 137 +
108 137 +
109 137 -
108 138 +
108 138 +
108 138 +
108 138 +
112 138 +
112 139 +
119 141 +
116 143 +
121 145 +
127 145 -
119 146 +
121 148 +
142 169 -
142 169 -
160 185 -
162 185 -
165 185 -

результат:

My graph

1 Ответ

2 голосов
/ 08 марта 2012

Извините, у меня нет времени на проработанный пример, но segments() (как и другие функции, такие как polygons(), points() и т. Д., Могут принимать свои аргументы в качестве векторов, так что вы можетевсе рисование выполняется одним вызовом функции. Зачастую подготовка аргументов перед построением графиков (apply() вставка или зацикливание при необходимости) может быть намного быстрее, чем повторные вызовы этих функций рисования. Ответ в этом посте: Plottingдовольно сложный график, использующий R и ось break () , дает полный пример этого подхода. Вы определенно сможете применить это в своей ситуации. Удачи! (и спасибо, что сказали мне ответить)

...