data.frame и разбиение строк... не найдено подходящее решение для моих данных
Я немного борюсь со своими столами. Я пытаюсь разделить некоторые переменные (используя R), но у меня возникают трудности с одним конкретным столбцом.
Мой набор данных выглядит так:
test<-data.frame(
Chrom_no=c(1,1,2,3),
Region=c('12..13','22..23','100','34..36'),
Ref=c('AT','CG','A','AAA'),
Alt=c('TA','GA','T','CGG'),
Prob=c(99,98.7,99,99.9))
Я хочу отделить все регионы, которые сгруппированы вместе. Пока что я решил для всех столбцов, кроме "Регион":
ref2 <- strsplit(as.character(test$Ref), '')
alt2<-strsplit(as.character(test$Alt), '')
test2<-data.frame(
Chrom_no=rep(test$Chrom_no, vapply(ref2, FUN=length, FUN.VALUE=integer(1))),
Region=rep(test$Region, vapply(ref2, FUN=length, FUN.VALUE=integer(1))),
Ref=unlist(ref2),
Alt=unlist(alt2),
Prob=rep(test$Prob, vapply(ref2, FUN=length, FUN.VALUE=integer(1))))
Я не знаю, как решить, исправить этот столбец: например, '12..13': 12 должно идти на Ref=A и 13 должно идти на Ref=T (первый и второй символ, соответственно). Все усложняется, так как некоторые столбцы имеют 3 символа (и соответствующий диапазон: 22..24), а некоторые будут иметь больше.
Как я мог решить? Я искал решение в последние пару дней, но я все еще не уверен, как решить. Я прошу прощения, если это уже было решено где-то еще. PS: я знаю, что для того, чтобы strsplit на столбце "Регион" мне нужно использовать:
'\\..'
в качестве разделителя.
1 ответ
Если я правильно понимаю вашу конечную цель, вы можете использовать пакет data.table. С его помощью вы можете настроить свою проблему следующим образом:
library(data.table)
## Change your data.frame to a data.table
DT <- as.data.table(test)
## Convert the relevant columns to be characters instead of factors
DT[, c("Region", "Ref", "Alt") := lapply(.SD, as.character),
.SDcols = c("Region", "Ref", "Alt")]
DT[, list(Chrom_no = rep(Chrom_no, nchar(Ref)), # Expand the Chrom_no
Region = unlist(lapply( # Split Region and use
strsplit(Region, "..", TRUE), # the result to create
function(x) { # the range of values
x <- as.numeric(x) # needed
if (length(x) > 1) seq(x[1], x[2]) else x
})),
Ref = unlist(strsplit(Ref, "")), # Split Ref
Alt = unlist(strsplit(Alt, "")), # Split Alt
Prob = rep(Prob, nchar(Ref)))] # Expand Prob
# Chrom_no Region Ref Alt Prob
# 1: 1 12 A T 99.0
# 2: 1 13 T A 99.0
# 3: 1 22 C G 98.7
# 4: 1 23 G A 98.7
# 5: 2 100 A T 99.0
# 6: 3 34 A C 99.9
# 7: 3 35 A G 99.9
# 8: 3 36 A G 99.9
Приведенный выше код, возможно, можно немного упростить, но я подумал, что этого должно быть достаточно, чтобы начать работу.