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