This is a test version of Biostars. For the public version, visit https://www.biostars.org.
Split comma seperated list of GO terms into multiple rows and maintain gene identifier in each

I have a tab separated dataset, although the GO terms are comma separated.

GENEID1   GO:XXXXX,GO:YYYYYY,GO:ZZZZZZ

I want to make it so that the dataset becomes a tab-seperated dataset where each GO term is represented on a new line with the gene identifier:

GENEID1  GO:XXXXX
GENEID1  GO:YYYYYY
GENEID1  GO:ZZZZZZ

Many thanks.

gene ontology data manipulation

I added markup to your post for increased readability. You can do this by selecting the text and clicking the 101010 button. When you compose or edit a post that button is in your toolbar, see image below:

101010 Button

Is it all tab separated? there are what look like tabs and commas in your example input.

A perl one liner could be

perl -ane '{print map {$F[0]."\t".$_."\n" } @F[1..$#F] }' your_input_file |sed -s 's/,$//'

This outputs the same as the input if your_input_file is created with echo -e "GENEID1\tGO:XXXXX,GO:YYYYYY,GO:ZZZZZZ" > your_input_file. Might there be a slight typo?

3 answers

Do you want to do this in R (possible) or other tools (also possible)?

echo -e "GENEID1\tGO:XXXXX,GO:YYYYYY,GO:ZZZZZZ" > test.txt

in R

library("tidyr")
test <- read.table("test.txt",sep = "\t",header=F)
test
V1                           V2
1 GENEID1 GO:XXXXX,GO:YYYYYY,GO:ZZZZZZ

# use tidyr separate rows to  convert A1\tGO:1,GO:2 to
#                                     A1  GO:1
#                                     A1  GO:2
test2 <- tidyr::separate_rows(data = test,V2,sep = ",")

test2
V1        V2
1 GENEID1  GO:XXXXX
2 GENEID1 GO:YYYYYY
3 GENEID1 GO:ZZZZZZ

Many thanks for the R version!

If an answer was helpful, you should upvote it; if the answer resolved your question, you should mark it as accepted. You can accept more than one if they work.
Upvote|Bookmark|Accept

My Apologies for the mistake Can you please try this -

cat your_input_file |perl -ane '{print map {$F[0]."\t".$_."\n" } split (/,/,$F[1]) }'

Perfect! This works. Thanks very much!

#!/usr/bin/env python
import sys

with open(sys.argv[1], 'r') as f:
    for line in f:
        for n in range(len(line.strip().split('\t')[1].split(','))):
            print line.strip().split('\t')[0] + 't' + line.strip().split('\t')[1].split(',')[n]

Save as go_tab.py, run as python go_tabl.py input.txt > output.txt

Many thanks for the python version also!

Log in to answer this question.