编辑:没有重叠的一列和公共变量的组合

Edit : combination of one column without overlap and common variable

数据已更新!

我有一个示例数据集

Target Start sequence
A y1 ccc
A y2 cct
A y3 aag
A y3 act
B y1 aaa
B y4 aat

并尝试像 R 中那样获取数据集:

Target Start Start sequence
A y1 y2 ccc,cct
A y1 y3 ccc,aag,act
A y2 y3 cct,aag,act
B y1 y4 aaa,aat

起始列总是有一个目标,并从起始列的每个组合中寻找共同的目标,没有任何重叠及其序列列表。 我尝试使用 mutate() 和 comb() 帮助操作以下 link:link,但是没有达到想要的结果。

谁能帮助我,给我一个进一步学习的机会?

您可以通过对每个组使用 combn 来实现。

library(dplyr)
library(tidyr)

df %>%
  group_by(Target) %>%
  summarise(Start = combn(Start, 2, function(x) 
                           list(setNames(x, c('start', 'end')))), 
            Sequence = combn(sequence, 2, toString), .groups = 'drop') %>%
  unnest_wider(Start)

# Target start end   Sequence
#  <chr>  <chr> <chr> <chr>   
#1 A      y1    y2    ccc, cct
#2 A      y1    y3    ccc, aag
#3 A      y2    y3    cct, aag
#4 B      y1    y4    aaa, aat

这是不使用 combn() 的另一种 tidyverse 方法。

  1. group_by(Target, Start) 这样任何具有相同 TargetStart 的序列都可以折叠成一行
  2. 删除 Start 列到 group_by()
  3. Start列改为数值,这样我们就可以直接比较Start
  4. 创建一个包含Start值大于自身的Start2列,并提取对应的sequence字符串存入sequence2
  5. 根据 Start2sequence2 扩展数据框(因为 sapply 每行会有多个输出)
  6. group_by(Target, Start, Start2) 这样我们就可以 paste sequencesequence2
library(tidyverse)

df %>% 
  group_by(Target, Start) %>% 
  summarize(sequence = paste0(sequence, collapse = ","), .groups = "drop_last") %>% 
  mutate(Start_num = as.numeric(str_extract(Start, "\d+")),
         Start2 = sapply(Start_num, function(x) Start[which(Start_num > Start_num[x])]),
         sequence2 = sapply(Start_num, function(x) sequence[which(Start_num > Start_num[x])])) %>% 
  unnest(cols = c(Start2, sequence2)) %>% 
  group_by(Target, Start, Start2) %>% 
  summarize(sequence = paste0(c(sequence, sequence2), collapse = ","), .groups = "drop")

# A tibble: 4 × 4
  Target Start Start2 sequence   
  <chr>  <chr> <chr>  <chr>      
1 A      y1    y2     ccc,cct    
2 A      y1    y3     ccc,aag,act
3 A      y2    y3     cct,aag,act
4 B      y1    y4     aaa,aat