structure(list(ref = c("A", "C", "A", "G", "C"), alt = c("T,TAA,TAAAA,TAAAAA",
"G,GC,GCCG", "T", "A G", "G"), chr = c("chr1", "chr1",
"chr1", "chr1", "chr2"), pos_s = c(2313007, 2456780, 2578901,
2689511, 18907652), pos_e = c(2313009, 2456784, 2578903, 2689513,
18907654), format = c("GT:AD", "GT:AD", "GT:AD", "GT:AD", "GT:AD"
), info = c("0/1/2/3/4:296,5,33,29,55", "0/1/2/3:376,22,13,7",
"0/1:323,24", "0/1:288,21", "0/1:3342,25")), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -5L))
Вот фрейм данных, в котором столбцы alt и info содержат символы, разделенные разными символами, такими как запятая, косая черта и двоеточие. Я хочу переместить эти символы в разные строки и сохранить остальные столбцы. Сложность заключается в том, что информационная колонка содержит различные данные и различные виды символов.
Вот пример, который я ожидаю.
structure(list(ref = c("A", "A", "A", "A", "C", "C", "C", "A",
"G", "C"), alt = c("T", "TAA", "TAAAA", "TAAAAA", "G", "GC",
"GCCG", "T", "A G", "G"), chr = c("chr1", "chr1", "chr1", "chr1",
"chr1", "chr1", "chr1", "chr1", "chr1", "chr2"), pos_s = c(2313007,
2313007, 2313007, 2313007, 2456780, 2456780, 2456780, 2578901,
2689511, 18907652), pos_e = c(2313009, 2313009, 2313009, 2313009,
2456784, 2456784, 2456784, 2578903, 2689513, 18907654), format = c("GT:AD",
"GT:AD", "GT:AD", "GT:AD", "GT:AD", "GT:AD", "GT:AD", "GT:AD",
"GT:AD", "GT:AD"), info = c("0/1:296,5", "0/2:296,33", "0/3:296,29",
"0/4:296,55", "0/1:376,22", "0/2:376,13", "0/3:376,7", "0/1:323,24",
"0/1:288,21", "0/1:3342,25")), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -10L))
Я пробовал несколько вариантов этого, но ни один из них не работает. Есть идеи?
Спасибо за ваш ответ, но, вероятно, это не подходящий ответ на мой вопрос, потому что информационная колонка моих данных сложнее, чем она.
Следующее достигает того, что вы хотите. В первую очередь используются следующие функции/соображения:
separate_long_delim
разбивает запись, разделенную запятыми, на несколько строк, дублируя другие столбцы;str_extract_all
по шаблону \\d+
находит все цифры;info
позволяет вытягивать правильные цифры.Вам придется расширить конструкцию strippedinfo
, если ваша строка info
содержит более 4 элементов /
.
library(tidyverse)
d <- structure(
list(
ref = c("A", "C", "A", "G", "C"),
alt = c("T, TAA, TAAAA, TAAAAA", "G, GC, GCCG", "T", "A.G", "G"),
chr = c("chr1", "chr1", "chr1", "chr1", "chr2"),
pos_s = c(2313007, 2456780, 2578901, 2689511, 18907652),
pos_e = c(2313009, 2456784, 2578903, 2689513, 18907654),
format = c("GT:AD", "GT:AD", "GT:AD", "GT:AD", "GT:AD"),
info = c("0/1/2/3/4:296,5,33,29,55", "0/1/2/3:376,22,13,7","0/1:323,24", "0/1:288,21", "0/1:3342,25")
),
class = c("tbl_df", "tbl", "data.frame"),
row.names = c(NA, -5L)
)
stripinfo <- function (infostring) {
digext <- str_extract_all(
string = infostring,
pattern = '\\d+'
)[[1]]
strippedinfo <- switch(
EXPR = str_count(
string = infostring,
pattern = '/'
),
infostring, # Only 1 '/' found
paste(
paste0('0/1:', digext[4], ';', digext[5]),
paste0('0/2:', digext[4], ';', digext[6]),
sep = ','
), # Two '/' found
paste(
paste0('0/1:', digext[5], ';', digext[6]),
paste0('0/2:', digext[5], ';', digext[7]),
paste0('0/3:', digext[5], ';', digext[8]),
sep = ','
), # Three '/' found
paste(
paste0('0/1:', digext[6], ';', digext[7]),
paste0('0/2:', digext[6], ';', digext[8]),
paste0('0/3:', digext[6], ';', digext[9]),
paste0('0/4:', digext[6], ';', digext[10]),
sep = ','
), # Four '/' found
paste(infostring, '!') # Add more here...
)
return(strippedinfo)
}
d
d %>% mutate(
info = str_replace_all(
string = info,
pattern = ',',
replacement = ';'
) %>% map_chr(
.f = stripinfo
)
) %>% separate_longer_delim(
cols = c(
alt, info
),
delim = stringr::regex('\\s*,\\s*')
) %>% mutate(
info = str_replace(
string = info,
pattern = ';',
replacement = ','
)
)
Выход:
# A tibble: 10 x 7
ref alt chr pos_s pos_e format info
<chr> <chr> <chr> <dbl> <dbl> <chr> <chr>
1 A T chr1 2313007 2313009 GT:AD 0/1:296,5
2 A TAA chr1 2313007 2313009 GT:AD 0/2:296,33
3 A TAAAA chr1 2313007 2313009 GT:AD 0/3:296,29
4 A TAAAAA chr1 2313007 2313009 GT:AD 0/4:296,55
5 C G chr1 2456780 2456784 GT:AD 0/1:376,22
6 C GC chr1 2456780 2456784 GT:AD 0/2:376,13
7 C GCCG chr1 2456780 2456784 GT:AD 0/3:376,7
8 A T chr1 2578901 2578903 GT:AD 0/1:323,24
9 G A.G chr1 2689511 2689513 GT:AD 0/1:288,21
10 C G chr2 18907652 18907654 GT:AD 0/1:3342,25
Большое спасибо за Вашу помощь. Это решение дало мне много идей. Могу я спросить, как удалить дубликаты из обработанных вами данных? Результат, полученный при этом, содержит больше строк, чем я ожидал. Еще раз спасибо за вашу помощь.
@Pokemoon: Мои извинения; Я исправил трубу, чтобы объединить разделение строк, а не делать их по отдельности. Смотрите обновленный ответ.
Отличное решение моей проблемы! Большое спасибо!
Отвечает ли это на ваш вопрос? Разделить столбец строки фрейма данных на несколько столбцов