## Get median marker expression per sample and cluster

expr_median_sample_cluster_tbl <- data.frame(expr[, functional_markers], 
  sample_id = sample_ids, cluster = cell_clustering1m) %>%
  group_by(sample_id, cluster) %>% 
  summarize_all(funs(median))

expr_median_sample_cluster_melt <- melt(expr_median_sample_cluster_tbl, 
  id.vars = c("sample_id", "cluster"), value.name = "median_expression", 
  variable.name = "antigen")

## Rearange so the rows represent clusters and markers

expr_median_sample_cluster <- dcast(expr_median_sample_cluster_melt, 
  cluster + antigen ~ sample_id,  value.var = "median_expression")

rownames(expr_median_sample_cluster) <- paste0(expr_median_sample_cluster$cluster, 
  "_", expr_median_sample_cluster$antigen)

## Eliminate clusters with low frequency

clusters_keep <- names(which((rowSums(counts < 5) == 0)))

keepLF <- expr_median_sample_cluster$cluster %in% clusters_keep

## Eliminate cases with zero expression in all samples

keep0 <- rowSums(expr_median_sample_cluster[, md$sample_id]) > 0