Я думаю, что лучший способ сделать это был бы с помощью следующих пакетов dplyr
, tidyr
и magrittr
.
Сначала вы должны сгенерировать воспроизводимый пример
library(magrittr)
library(dplyr)
library(tidyr)
#Reproducible example
Nucleo <- c("A","T","G","C")
df <- data.frame(gene=paste0("Gene",1:20))
for(x in 1:21){
df[[paste0("pos_",x)]] <- sample(Nucleo, 20, replace = T)
}
Далее мы сделаем блок данных аккуратным, чтобы мы могли им манипулировать.
df <- gather(df, key = "Position", value = "Nucleotide", -gene)
frequency <- df %>%
group_by(gene, Nucleotide) %>% #specify which groups we will mutate on
mutate(NucleotitdeCount=n()) %>% #For each gene and Nucleotide type - Count total
select(gene, Nucleotide, NucleotitdeCount) %>% #Specify Columns we need
distinct() %>% ungroup() %>% #reduce size to unique instances
group_by(gene) %>% #Regroup by gene to mutate over nucleotide counts
mutate(relativeFreq=NucleotitdeCount/sum(NucleotitdeCount)) #Calculate Relative Frequency
Я считаю, что лучше оставить данные как есть, но если вы хотите вернуть их в длинный формат:
freqLong <- frequency %>%
select(gene, Nucleotide, relativeFreq) %>%
spread(key = "Nucleotide", value = "relativeFreq")
Оставив его в прежней форме, можно легко сделать визуализацию с пакетом ggplot2
library(ggplot2)
ggplot(frequency, aes(gene, relativeFreq, fill = Nucleotide)) +
geom_bar(stat = "identity", position = "stack")
Преимущество такого способа состоит в том, что вам не нужно беспокоиться о фильтрации вначале.
Однако, если вы сначала захотите sh отфильтровать гены, это также можно сделать с помощью функции dplyr filter
Я рекомендую использовать ее вместе с grepl
для сопоставление с образцом. это пример, где я сопоставляю «seto» в столбце «Виды» набора данных iris
iris %>% filter(grepl(pattern = "seto", x = Species)) %>% head()
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1 5.1 3.5 1.4 0.2 setosa
#2 4.9 3.0 1.4 0.2 setosa
#3 4.7 3.2 1.3 0.2 setosa
#4 4.6 3.1 1.5 0.2 setosa
#5 5.0 3.6 1.4 0.2 setosa
#6 5.4 3.9 1.7 0.4 setosa