Skip to main content
added 206 characters in body
Source Link

One change I would make to your solution is to directly modify the row names as below (instead of modifying modifying gene and then setting the row names equal to gene).

for (i in 1:nrow(df)){
  if (rownames(df)[i] %in% annotation$gene) {
    
    rownames(df)[i] = annotation$name[which(annotation$gene == rownames(df)[i])]
    
  }
}
df$gene <- NULL

df
#        sample_1 sample_2
# name_1        0        0
# name_2        0        0
# gene_3        0        0

This versionsolution is quite similar to yoursthe original, but iterates over row numbers (1-3 in this case) instead of row names. This allows direct modification of the row names and makes the code slightly more concise. This version doesn't use gene at all.

This isThat's how I wouldI'd modify yourthe existing solution, but overall I'd caution against usingI wouldn't use a for loop at all. for loops can be slow since they iterate over every element (and your data set has 10^5 rows). Below is another approach using the dplyr library.

library(dplyr)
library(tibble)

df <- left_join(df, annotation, by = "gene") %>%              # Join "annotation" and "df"
      mutate(gene = if_else(is.na(name), gene, name)) %>%     # Convert "gene" to "name" when "name" is valid
      column_to_rownames(var = "gene") %>%                    # Set row names to "gene"
      select(-name)                                           # Remove "name"

df
#        sample_1 sample_2
# name_1        0        0
# name_2        0        0
# gene_3        0        0

One change I would make to your solution is to directly modify the row names as below (instead of modifying gene and then setting the row names equal to gene).

for (i in 1:nrow(df)){
  if (rownames(df)[i] %in% annotation$gene) {
    
    rownames(df)[i] = annotation$name[which(annotation$gene == rownames(df)[i])]
    
  }
}
df$gene <- NULL

This version is quite similar to yours, but iterates over row numbers (1-3 in this case) instead of row names. This allows direct modification of the row names and makes the code slightly more concise. This version doesn't use gene at all.

This is how I would modify your existing solution, but overall I'd caution against using a for loop at all. for loops can be slow since they iterate over every element (and your data set has 10^5 rows). Below is another approach using the dplyr library.

library(dplyr)
library(tibble)

df <- left_join(df, annotation, by = "gene") %>%              # Join "annotation" and "df"
      mutate(gene = if_else(is.na(name), gene, name)) %>%     # Convert "gene" to "name" when "name" is valid
      column_to_rownames(var = "gene") %>%                    # Set row names to "gene"
      select(-name)                                           # Remove "name"

One change I would make to your solution is to directly modify the row names as below (instead of modifying gene and then setting the row names equal to gene).

for (i in 1:nrow(df)){
  if (rownames(df)[i] %in% annotation$gene) {

    rownames(df)[i] = annotation$name[which(annotation$gene == rownames(df)[i])]

  }
}
df$gene <- NULL

df
#        sample_1 sample_2
# name_1        0        0
# name_2        0        0
# gene_3        0        0

This solution is similar to the original, but iterates over row numbers (1-3 in this case) instead of row names. This allows direct modification of the row names and makes the code slightly more concise. This version doesn't use gene at all.

That's how I'd modify the existing solution, but overall I wouldn't use a for loop. for loops can be slow since they iterate over every element (and your data set has 10^5 rows). Below is another approach using the dplyr library.

library(dplyr)
library(tibble)

df <- left_join(df, annotation, by = "gene") %>%        # Join "annotation" and "df"
mutate(gene = if_else(is.na(name), gene, name)) %>%     # Convert "gene" to "name" when "name" is valid
column_to_rownames(var = "gene") %>%                    # Set row names to "gene"
select(-name)                                           # Remove "name"

df
#        sample_1 sample_2
# name_1        0        0
# name_2        0        0
# gene_3        0        0
Source Link

Code Review

One change I would make to your solution is to directly modify the row names as below (instead of modifying gene and then setting the row names equal to gene).

for (i in 1:nrow(df)){
  if (rownames(df)[i] %in% annotation$gene) {
    
    rownames(df)[i] = annotation$name[which(annotation$gene == rownames(df)[i])]
    
  }
}
df$gene <- NULL

This version is quite similar to yours, but iterates over row numbers (1-3 in this case) instead of row names. This allows direct modification of the row names and makes the code slightly more concise. This version doesn't use gene at all.

This is how I would modify your existing solution, but overall I'd caution against using a for loop at all. for loops can be slow since they iterate over every element (and your data set has 10^5 rows). Below is another approach using the dplyr library.

Another Approach

library(dplyr)
library(tibble)

df <- left_join(df, annotation, by = "gene") %>%              # Join "annotation" and "df"
      mutate(gene = if_else(is.na(name), gene, name)) %>%     # Convert "gene" to "name" when "name" is valid
      column_to_rownames(var = "gene") %>%                    # Set row names to "gene"
      select(-name)                                           # Remove "name"

This syntax may look unfamiliar but it's doing 3 main things:

  • left-joining df and annotation by the gene field. It has to be a left-join so all rows of df are preserved!
  • changing the value of gene to name only when name is non-null
  • setting the row names equal to gene

The pipe operator %>% passes the data through these operations without needing to repeatedly type df <-. These are all vectorized operations and so are faster than a for loop, especially for large data sets.

dplyr syntax can be intimidating at first, but it's an extremely popular (and I believe intuitive) paradigm to manipulate data. Here is a handy intro on dplyr syntax.