I have a dataset that contains IDs and associated Gene Ontology (GO) IDs. Some of the IDs have multiple GO IDs assigned to them, and I'm unsure how to handle this situation. I would like to determine whether Should I split all Go id or I should use the first or last GO ID in the hierarchy when assigning the GO ID to the ID.

Here is an example of my data:

3667 FEHLGCFF_05007                                             GO:0006637|GO:0047617
3673 FEHLGCFF_05919                                  GO:0016020|GO:0022857|GO:0055085
3684 FEHLGCFF_00369                                             GO:0022857|GO:0055085
3695 FEHLGCFF_00369                                  GO:0016020|GO:0022857|GO:0055085
3696 FEHLGCFF_00369                                                        GO:0022857
3702 FEHLGCFF_06641                                                        GO:0016627
3707 FEHLGCFF_06641                                                        GO:0003995
3721 FEHLGCFF_04414                                                        GO:0046872
3725 FEHLGCFF_02968                                  GO:0003700|GO:0006352|GO:0006355

How should I handle cases where an ID has multiple GO IDs assigned to it? Should I split all Go id or Should I use the first GO ID, the last GO ID, or is there another approach I should consider?

Any guidance or best practices would be greatly appreciated. Thank you!

Here is My code using R, it it Ok


# Read the go-basic.obo file
go_data <- readLines("go-basic.obo")

# Extract the GO ID and Gene ID from the unique_data dataframe
unique_data <- unique_data %>%
  separate_rows(GO_ID, sep = "\\|") %>%
  select(V1, GO_ID) # Replace with the correct column names from your unique_data dataframe

# Create an empty dataframe to store the results
result <- data.frame(Gene_ID = character(), GO_ID = character(), Name = character(), Namespace = character(), stringsAsFactors = FALSE)

# Process each line in the go-basic.obo file
for (i in 1:(length(go_data) - 1)) {
  line <- go_data[i]
  if (grepl("^id:", line)) {
    go_id <- strsplit(line, " ")[[1]][2]
    # Check if the current GO ID exists in the unique_data dataframe
    if (go_id %in% unique_data$GO_ID) {
      # Filter the unique_data dataframe for the current GO ID
      filtered_data <- unique_data %>% filter(GO_ID == go_id)
      # Extract the name and namespace information
      name <- ""
      namespace <- ""
      while (!grepl("^is_a:", go_data[i])) {
        if (grepl("^name:", go_data[i])) {
          name <- strsplit(go_data[i], "name: ")[[1]][2]
        } else if (grepl("^namespace:", go_data[i])) {
          namespace <- strsplit(go_data[i], "namespace: ")[[1]][2]
        i <- i + 1
      # Add the information to the result dataframe
      temp_df <- data.frame(Gene_ID = filtered_data$V1, GO_ID = go_id, Name = name, Namespace = namespace, stringsAsFactors = FALSE) # Replace with the correct column names
      result <- bind_rows(result, temp_df)

# Print the result dataframe
  • $\begingroup$ What do you want to do with this data? GO terms of deep down the hierarchy also imply the upper nodes (genes annotated in the olfactory sensors term are also part of the biological process term). $\endgroup$
    – llrs
    Jul 6 at 7:25
  • $\begingroup$ @ I I have seen in papers, they classify in GO terms and give good bar graphs with frequency, whith three terms, but I got this kind of confusing, so I am confused which one is correct, for publishing paper $\endgroup$
    – Umar
    Jul 6 at 7:50
  • 1
    $\begingroup$ There are three branches of GO terms, BP, biological process, CC, cellular components and MF molecular functions. All three are correct, for publishing, it only depends on what do you want to focus on. They are independent of each other, that's why they are split/classified in three terms. $\endgroup$
    – llrs
    Jul 6 at 8:39
  • $\begingroup$ I think I should delete this question $\endgroup$
    – Umar
    Jul 10 at 8:25
  • $\begingroup$ Dear @umar I am afraid that deleting a question with an upvoted answer is not permitted. It is fair to point out both llrs and RicardoA.'s answer are reasonable contributions. Also RicardoA's comment about how you obtain GO assignments is good. $\endgroup$
    – M__
    Jul 23 at 12:44

1 Answer 1


You might want to look at Revigo to simplify multiple GO terms into their parent terms. I've used rrvgo extensively to simplify enrichment results - this is the R implementation of Revigo.

It's not clear how exactly you are obtaining these GO assignments. If these are the significant hits for each feature, I'd take the union of all significant GO terms (i.e. everything in your second column combined) and pass it to rrvgo. Then, you can select the parent term associated with each row. I don't guarantee each row will be collapsed to a single term, but it should make whatever you are doing downstream much more tractable.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.