I have a `data.frame` with 48 columns. the columns are samples in triplicates, the rows are genes. The values are expression values.


For each group of triplicates I would like to calculate the averaged expression per gene, resulting in a new `data.frame` with 16 columns and for each row the average of the three triplicates for each group.

can this be done with the `tidyverse` tools?

thanks

a small example table of 6x9 is here

    dput(head(normCounts[,1:9]))
    structure(c(0, 4.89997034943019, 2.4499851747151, 0, 46.5497183195869, 
    14.6999110482906, 0.998187766715749, 1.9963755334315, 0, 0.998187766715749, 
    55.898514936082, 7.98550213372599, 0, 1.57112407949228, 0, 1.57112407949228, 
    53.4182187027374, 4.71337223847683, 0, 1.25548317693578, 0, 0, 
    52.7302934313026, 10.0438654154862, 0, 0, 0, 0, 66.3962127189125, 
    23.2386744516194, 2.18533123780511, 3.27799685670766, 0, 0, 65.5599371341532, 
    9.83399057012298, 0, 0, 0, 0, 74.1086143860152, 18.9580176336318, 
    0, 0, 0, 0, 66.8826789069951, 13.376535781399, 0, 0, 0, 0, 50.7776960416371, 
    13.0791035258762), .Dim = c(6L, 9L), .Dimnames = list(c("ENSMUSG00000103147", 
    "ENSMUSG00000102269", "ENSMUSG00000096126", "ENSMUSG00000102735", 
    "ENSMUSG00000098104", "ENSMUSG00000102175"), c("Sample_1", "Sample_2", 
    "Sample_3", "Sample_4", "Sample_5", "Sample_6", "Sample_7", "Sample_8", 
    "Sample_9")))
It will be a lot simpler to first make a group key table.

    library("tidyverse")

    groups <- tibble(
      sample=colnames(normCounts),
      group=rep(seq(1, ncol(normCounts)/3), each=3)
    )
    
    > groups
    # A tibble: 9 x 2
      sample   group
      <chr>    <int>
    1 Sample_1     1
    2 Sample_2     1
    3 Sample_3     1
    4 Sample_4     2
    5 Sample_5     2
    6 Sample_6     2
    7 Sample_7     3
    8 Sample_8     3
    9 Sample_9     3

Then you can pivot your count data to long format, join the groups, and group_by/summarize to get the means.

    mean_exp <- normCounts %>%
      as_tibble(rownames="gene") %>%
      pivot_longer(starts_with("Sample"), names_to="sample", values_to="counts") %>%
      left_join(groups, by="sample") %>%
      group_by(gene, group) %>%
      summarize(mean_count=mean(counts))
    
    > head(mean_exp)
    # A tibble: 6 x 3
    # Groups:   gene [2]
      gene               group mean_count
      <chr>              <int>      <dbl>
    1 ENSMUSG00000096126     1      0.817
    2 ENSMUSG00000096126     2      0    
    3 ENSMUSG00000096126     3      0    
    4 ENSMUSG00000098104     1     52.0  
    5 ENSMUSG00000098104     2     61.6  
    6 ENSMUSG00000098104     3     63.9

You can pivot back to a wider format if you want too.

    mean_exp_wider <- pivot_wider(mean_exp, names_from=group, values_from=mean_count)
    
    > mean_exp_wider
    # A tibble: 6 x 4
    # Groups:   gene [6]
      gene                  `1`    `2`   `3`
      <chr>               <dbl>  <dbl> <dbl>
    1 ENSMUSG00000096126  0.817  0       0  
    2 ENSMUSG00000098104 52.0   61.6    63.9
    3 ENSMUSG00000102175  9.13  14.4    15.1
    4 ENSMUSG00000102269  2.82   1.51    0  
    5 ENSMUSG00000102735  0.856  0       0  
    6 ENSMUSG00000103147  0.333  0.728   0  

