Изменение во вложенном столбце для получения результатов в неподдерживаемом классе (data.frame) - PullRequest
0 голосов
/ 01 февраля 2019

В настоящее время у меня есть поиск по мотивам, работающий в серии циклов for, и я хотел бы перейти к вложенной таблице, чтобы улучшить скорость и простоту (иш).Тем не менее, я не могу понять, как хранить тиббл внутри тиббла, чтобы потом его развернуть.Если это невозможно, советы по тому, как передать списки (и столбец идентификатора), чтобы я мог позже присоединить его к исходной таблице, будут с благодарностью.

Ввод: набор координат и соответствующая последовательность ДНК

Цели:
1) Найти экземпляры мотива, который мне небезразличен
2) Объединить их с началом или концомдиапазон для создания всех пар начальных и конечных точек (где может быть любая найденная позиция)
3) Определить тип спаривания

Я не могу понять, как заставить мутировать, чтобы принять тибл (Ошибкав mutate_impl (.data, dots): столбец «пар» имеет неподдерживаемый класс data.frame).Здесь я не могу вызвать строку, потому что мне нужно отправить весь список позиций в функцию, а также значения из других столбцов.

test_input = tibble(
  start = c(1,10,15), 
  end = c(9, 14, 25),  
  sequence = c("GAGAGAGTC","CATTT", "TCACAGTTTCC")
)

custom_function = function(start, end, list.of.positions) {
  ## Doesn't include extra math, case specifications, and error handling here for simplicity
  starts = c(start, list.of.positions)
  ends = c(end, list.of.positions)
  pairs = expand.grid(starts, ends) %>% as_tibble %>% 
    mutate(type = case_when(TRUE ~ "a_type")) #Simplified for example to one case 
  return(pairs)
}

test_input %>% 
# for each set of coordinates/string
  rowwise() %>% 
  # find the positions of a given motif
  mutate(match.positions = regexp.match.ends(gregexpr("AG", sequence))) %>% 
  mutate(num.matches = case_when(
    is_logical(match.positions) ~ NA_integer_,
    TRUE ~ length(match.positions) 
  )) %>% 
  # expand and covert to real positions
  unnest %>% rowwise %>% 
  mutate(true.positions = case_when(
    is.na(match.positions) ~ NA_real_, #must be a double-compatible NA
    TRUE ~ start + match.positions - 1)) %>% 
  select(-match.positions) %>% 
  ungroup() %>% 
  # re-"nest" into a list of real positions
  group_by_at(vars(-true.positions)) %>% 
  summarise(true.positions = list(true.positions)) %>% 
  # pass list of real positions to a function that creates pairs of coordinates and determines the type of pair
  mutate(pairs = custom_function(start, end, true.positions))

Мой последний тиббл должен выглядеть так (после удаления пар):

  start   end  sequence      new.start  new.end   type  
  <dbl> <dbl>  <chr>         <dbl>      <dbl>    <chr>   
1     1     9  GAGAGAGTC     1          3        a_type
1     1     9  GAGAGAGTC     1          5        a_type
2     1     9  GAGAGAGTC     1          7        a_type
3     1     9  GAGAGAGTC     1          9        a_type
4     1     9  GAGAGAGTC     3          5        a_type
...
10    1     9  GAGAGAGTC     7          9        a_type
11    10    14 CATTT         10         14       a_type
...

Один из обходных путей, о котором я подумал, - вставить выходные значения в строку и передать обратно каксписок, который терпит толпа, распускает и затем разделяет его, но, конечно, есть менее хакерский способ сделать это.Большое спасибо за вашу помощь / идеи!

1 Ответ

0 голосов
/ 01 февраля 2019

Так что я совсем не знаком с предметом.Но я думаю, что смогу собрать воедино то, что ты пытаешься сделать.Мне нравится использовать пакет stringr, поскольку он делает это с более простым синтаксисом.

test_input <- tibble(
  start = c(1,10,15), 
  end = c(9, 14, 25),  
  sequence = c("GAGAGAGTC","CATTT", "TCACAGTTTCC")
)

custom_function <- function(string, pattern, label) {
    string %>%
        str_locate_all(pattern) %>%    # get the start-end pairs.
        as.data.frame() %>%    # make it a data.frame
        expand.grid() %>%    # all combos. this seemed important.
        mutate(
            sequence = string,
            type = label
            ) %>%    # add the string and label to each row.
        %>% rename(
            new_start = start,    # rename so we don't confuse columns.
            new_end = end         # I prefer not to use dots in my names.
            ) %>%
        left_join(test_input) %>%    # add the original start and ends
        return()    # return df has cols: start, end, sequence, new_start, new_end, type.
}

final_out <- data.frame(
    start = numeric(0),
    end = numeric(0),
    sequence = character(0),
    new_start = numeric(0),
    new_end = numeric(0)
    )    # empty dummy DF that we'll add to.

for (string in test_input$sequence) {
    final_out <- custom_function(string = string,
                                 pattern = 'AG',
                                 label = 'a_type') %>%
        bind_rows(final_out)
}    # add the rows of each output to the final DF we made.

print(final_out)

Похоже, вы пытались пометить результат на основе предоставленного вами шаблона, поэтому вы можете указать 'a_type'или любой другой ярлык, который вы хотите.

Может быть способ сделать это без цикла for с помощью функции map или apply.Хотя мне придется больше повозиться, чтобы понять это.

Надеюсь, это поможет или, по крайней мере, приведет вас в правильном направлении.Как я уже сказал, я не знаком с предметом.

...