首页 > 解决方案 > 对嵌套列进行变异以导致不支持的类(data.frame)

问题描述

我目前有一个在一系列 for 循环中工作的主题搜索,并且想移动到嵌套的 tibble 以提高速度和简单性(ish)。但是,我无法弄清楚如何将 tibble 存储在 tibble 中,这样我就可以取消嵌套它。如果这是不可能的,关于如何传递列表(和一个 id 列)以便我以后可以将其加入原始表的提示将不胜感激。

输入:一组坐标和相应的 DNA 序列

目标:
1)找到我关心的主题的实例
2)将它们与范围的开始或结束相结合以创建所有开始和结束对(找到的位置可以是其中之一)
3)确定配对的类型

我无法弄清楚如何让 mutate 接受 tibble(mutate_impl(.data, dots) 中的错误:列 `pairs` 属于不受支持的类 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))

我最后的 tibble 应该是这样的(在取消嵌套对之后):

  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
...

我想到的一种解决方法是将输出值粘贴到一个字符串中并将其作为一个列表传回,tibble 可以容忍该列表,取消嵌套,然后将其分离,但肯定有一种不那么老套的方法来解决这个问题。非常感谢您的帮助/想法!

标签: rnesteddplyrtibble

解决方案


所以我对这个主题一点也不熟悉。但我想我可以把你想做的事情拼凑起来。我喜欢使用 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”或您想要的任何标签。

可能有一种方法可以通过使用maporapply函数在没有 for 循环的情况下执行此操作。不过,我必须修补更多才能弄清楚。

希望这会有所帮助,或者至少会引导您朝着正确的方向前进。就像我说的,我对主题不熟悉。


推荐阅读