2015-08-13 3 views
4

У меня есть эта таблица (Данные1) с четырьмя колоннамиРазделение строки в каждом столбце несколько столбцов

SNP rs6576700 rs17054099 rs7730126 
sample1 G-G T-T G-G 

мне нужно разделить столбцы 2-4 на две колонки каждый, так что новый выход имеет 7 столбцов. Например:

SNP rs6576700 rs6576700 rs17054099 rs17054099 rs7730126 rs7730126 
sample1 G G T T C C 

С помощью следующей функции я мог разделить все столбцы в то время, но результат не то, что мне нужно.

split <- function(x){ 
    x <- as.character(x) 
    strsplit(as.character(x), split="-") 
    } 

data2=apply(data1[,-1], 2, split) 

data2 
$rs17054099 
$rs17054099[[1]] 
[1] "T" "T" 


$rs7730126 
$rs7730126[[1]] 
[1] "G" "G" 


$rs6576700 
$rs6576700[[1]] 
[1] "C" "C" 

В Stack Overflow я нашел способ, чтобы преобразовать выход strsplit в dataframe но числа RS в строках не в столбцах (я получил аналогичный вывод с другими методами в этой теме strsplit by row and distribute results by column in data.frame)

> n <- max(sapply(data2, length)) 
> l <- lapply(data2, function(X) c(X, rep(NA, n - length(X)))) 
> data.frame(t(do.call(cbind, l))) 
      t.do.call.cbind..l.. 
rs17054099     T, T 
rs7730126     G, G 
rs2061700     C, C 

Если я не использую функцию транспонирования (... (т (do.call ...), выходной список, который я не могу записать в файл.

Я хотел бы иметь раствор в R, чтобы сделать его частью трубопровода.

Я забыл сказать, что мне нужно применить это к миллиону столбцов.

+0

Как вы планируете провести различие между столбцами с таким же именем? -hint: Вы не можете. Во-первых, вам нужно определить имена явных столбцов. – N8TRO

+0

В конце я не буду использовать заголовок. Я хочу сохранить его в первую очередь, чтобы быть уверенным в порядках SNP. Я могу добавить rs17054099.1 и rs17054099.2. Мне нужно создать файл plink ped, поэтому я добавлю информацию каждого образца (FID, IDD и т. Д.). Благодарим вас за интерес к моему вопросу. Sami – Sami

+0

Хорошо, спасибо за предложение. Если порядок столбцов не изменяется, заголовок не важен. – Sami

ответ

7

Это прямолинейно, используя функцию splitstackshape::cSplit. Просто укажите индексы столбцов в параметре splitCols и разделитель внутри параметра sep, и вы сделали это. Он даже будет содержать ваши новые имена столбцов, чтобы вы могли различать их. Я указал type.convert = FALSE, поэтому T значения не станут TRUE. По умолчанию используется wide, поэтому вам не нужно указывать его.

library(splitstackshape) 
cSplit(data1, 2:4, sep = "-", type.convert = FALSE) 
#  SNP rs6576700_1 rs6576700_2 rs17054099_1 rs17054099_2 rs7730126_1 rs7730126_2 
# 1: sample1   G   G   T   T   G   G 

Вот решение согласно предоставленной ссылке, используя tstrsplit функцию для devel version of data.table on GH. здесь мы определим индекс, сначала навстречу именам столбцов, а затем их будем указывать с помощью paste. Это немного более громоздкий подход, но его преимущество в том, что оно обновит исходные данные вместо создания копии целые данные

library(data.table) ## V1.9.5+ 
indx <- names(data1)[2:4] 
setDT(data1)[, paste0(rep(indx, each = 2), 1:2) := sapply(.SD, tstrsplit, "-"), .SDcols = indx] 
data1 
#  SNP rs6576700 rs17054099 rs7730126 rs65767001 rs65767002 rs170540991 rs170540992 rs77301261 rs77301262 
# 1: sample1  G-G  T-T  G-G   G   G   T   T   G   G 
+0

Привет, спасибо за ваш ответ. Я пробовал cSplit, и это не сработало. Я забыл добавить, что у меня есть файл с почти миллионом столбцов, поэтому мне нужен способ не указывать каждый столбец в то время. Спасибо, – Sami

+0

Что именно не сработало? Можете ли вы предоставить 'dput' вашего набора данных? См. Мое редактирование. Вы можете указать индексы столбцов вместо имен. Например, вы можете сделать что-то вроде «2: 1e3», например. –

+0

Должна быть моя ошибка, я не могу указать несколько столбцов splitGeno1 = cSplit (data1, splitcols = data1 [, 2: 4], seps = "-") Ошибка в cSplit (data2, splitcols = data2 [, 2: 4] , seps = "-"): неиспользуемые аргументы (splitcols = data2 [, 2: 4], seps = "-") – Sami

1

Здесь вы хотите использовать наносить поверх строки вместо столбцов:

df <- rbind(c("SNP", "rs6576700", "rs17054099", "rs7730126"), 
c("sample1", "G-G", "T-T", "G-G"), 
c("sample2", "C-C", "T-T", "G-C")) 

t(apply(df[-1,], 1, function(col) unlist(strsplit(col, "-")))) 
# [,1]  [,2] [,3] [,4] [,5] [,6] [,7] 
#[1,] "sample1" "G" "G" "T" "T" "G" "G" 
#[2,] "sample2" "C" "C" "T" "T" "G" "C" 
+0

Это «базовый» метод, гораздо медленнее, но все же отличный ответ. – N8TRO

+0

Спасибо Mattdevlin – Sami

Смежные вопросы