EDIT: Sorry, I did not see the R tag and wrote the code in bash. I still left the bash example below and added an R version.
Depends on what you want to do, but there are two common ways in which you could store this. Either as wide format:
h2 h4 h6 ...
Gene1 1 1 0
Gene2 0 1 1
Gene3 1 1 1
...
Where 1 denotes presence and 0 absence, or as long format:
timepoint
Gene1 h2
Gene1 h4
Gene2 h4
Gene2 h6
Gene3 h2
Gene3 h4
Gene3 h6
...
The best format probably depends on what you want to do. Since you did not specify a method/language, I took the liberty to write a few lines of bash to go from the gene lists to the matrices.
Bash examples assume your files are named h2, h4 etc and are tab separated with gene names in the first column. R examples assume tables
is a list of your data frames and timepoints
is a vector c("h2", "h4", ...)
.
Generate table in wide format:
- Concatenate gene names of all tables to a separate file
- Extract unique values in this file
- Perform outer join between the separate file and each table
R:
all_names <- c()
for (tp in timepoints){
all_names <- append(all_names, tables[[tp]]$genes)
}
all_names <- unique(all_names)
wide_table <- matrix(nrow=length(all_names), ncol=(1+length(timepoints)))
wide_table <- as.data.frame(wide_table)
colnames(wide_table) <- append("genes", timepoints)
for (tp in timepoints){
tmp <- tables[[tp]]
tmp$tp <- 1
tmp <- merge(wide_table, tmp, by="genes", all=T)
wide_table$tp <- tmp$tp
}
Bash:
Note: you will might need to add headers to this table
for timefile in $yourfiles;do
# make a file with all gene names
awk -v tp=$timefile '{print $1}' >> names_file
done
sort names_file | uniq > tmp && mv tmp names_file
for timefile in $yourfiles;do
join -a1 -a2 -j 1 -o 0,1.2,2.2 -e 0 $names_file <(awk '{print$1,1}' $timefile | sort)
done
Generate table in long format:
- For each table, add a column with timepoint
- Concatenate all tables
R:
df <- data.frame()
for (tp in timepoints){
tables[[tp]][[timepoint]] <- tp
df <- rbind(df, tables[[tp]] )
}
Bash:
for timefile in $yourfiles;do
awk -v tp=$timefile '{print $1,timefile}' >> long_table
done
EDIT2: To follow up on this, here is a simple way (using the package dplyr) to count the number of common genes between all possible combination of time points. Assuming you have your data in long format:
df <- data.frame(genes=c("G1","G1","G2","G3","G3"), tp=c("h2","h4","h2","h4","h6"))
genes tp
1 G1 h2
2 G1 h4
3 G2 h2
4 G3 h4
5 G3 h6
You can get the co-occurrences using :
library(dplyr)
# Make timepoint ordinal factor
df <- mutate(df, tp = factor(tp, ordered=T))
df <- df %>%
# Compute all pairwise co-occurrences
full_join(df, by="genes") %>%
group_by(tp.x, tp.y) %>%
summarise(N_genes = length(unique(genes))) %>%
# Exclude self pairs (gene in h2 and h2)
filter(tp.x != tp.y) %>%
# Check for duplicate pairs in reverse order (h2-h4 and h4-h2)
mutate(comb=ifelse(tp.x < tp.y,
yes = paste(tp.x, tp.y),
no = paste(tp.y, tp.x)))
# Remove the duplicate pairs
df <- df[which(!duplicated(df$comb)),]
And visualise it using for example a heatmap:
(ofc it looks stupid because I have a tiny sample where not all combinations are even present)
# Visualize number of genes present in each combination
library(ggplot2)
ggplot(df, aes(x=tp.x, y=tp.y, fill=N_genes)) + geom_tile()