在多个列上聚合 - 保留原始列名和结构

aggregate on multiple columns - keeping the original column names and structure

请考虑以下使用 aggregate 两次的示例。

library(dplyr)
set.seed(5)

x <- data.frame(
                name = sample(c('NM01', 'NM02', 'NM03', 'NM04', 'NM05'), 400, replace = TRUE),
                strand = sample(c('+', '-'), 400, replace = TRUE),
                value = sample(6, 400, replace = TRUE)
                )

x_agg_hist <- aggregate(    x$value, 
                            by = list(strand = x$strand, 
                                      transcript = x$name
                                      ), 
                            function(v) hist(   v, 
                                                breaks = seq(0.5, 6.5),
                                                plot= FALSE
                                                )$counts
                            )
                                
y <- data.frame(
                name = c('NM01', 'NM02', 'NM03', 'NM04', 'NM05'),
                value = runif(5)
                )
                
x_agg_hist$value <- y$value[match(x_agg_hist$transcript, y$name)]

x_agg_hist$division <- ifelse(x_agg_hist$value > 0.5, 1, 2) %>% as.factor()


x_agg_hist
   strand transcript x.1 x.2 x.3 x.4 x.5 x.6     value division
1       -       NM01   6   9   8   5   5   8 0.5661267        1
2       +       NM01   4   2   8   8   8   6 0.5661267        1
3       -       NM02   8   4   6   5   3  11 0.1178577        2
4       +       NM02   7   6   9   8   7   7 0.1178577        2
5       -       NM03   4   5  10   4   6   3 0.2572855        2
6       +       NM03   6  10   5   9   5   9 0.2572855        2
7       -       NM04   7   4   5   7   4   9 0.9678125        1
8       +       NM04   4   3   4  10   8   9 0.9678125        1
9       -       NM05   4   6  10   5   5   5 0.8891210        1
10      +       NM05  11  13   5   8  12   8 0.8891210        1

到目前为止,一切都很好。具体来说,我注意到我可以 select 由 aggregate 创建的直方图的列“集体”使用

x_agg_hist$x
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    6    9    8    5    5    8
 [2,]    4    2    8    8    8    6
 [3,]    8    4    6    5    3   11
 [4,]    7    6    9    8    7    7
 [5,]    4    5   10    4    6    3
 [6,]    6   10    5    9    5    9

接下来,我想通过 'division' 和 'strand' 对直方图求和(并根据每组中的观察数进行归一化)。

x_agg_hist_agg_sum <- aggregate(    x_agg_hist$x,
                                    by = list(division = x_agg_hist$division,
                                              strand = x_agg_hist$strand
                                              ), 
                                    function(v) sum(v)/length(v)
                                    )
                                

请注意,使用 x_agg_hist$x 到 select 直方图的所有列似乎比这里提出的方法方便得多 (Aggregate / summarize multiple variables per group (e.g. sum, mean))。

这仍然按预期工作。

x_agg_hist_agg_sum
  division strand       V1       V2       V3       V4       V5       V6
1        1      - 5.666667 6.333333 7.666667 5.666667 4.666667 7.333333
2        2      - 6.000000 4.500000 8.000000 4.500000 4.500000 7.000000
3        1      + 6.333333 6.000000 5.666667 8.666667 9.333333 7.666667
4        2      + 6.500000 8.000000 7.000000 8.500000 6.000000 8.000000

但是,现在 aggregate 以一种不允许 select 将它们集中在一起的方式重命名了(求和)直方图的列。因此,我想知道是否可以告诉聚合保留原始列名和结构,或者是否有任何其他方法可以这样做。 (当然我知道我可以使用 x_agg_hist_agg_sum[, -c(1, 2)],但使用我的真实数据(经过大量进一步处理后)这至少会更加困难。)

干杯,

mce1

我建议对这种长链操作使用 dplyr。它有很多好处。

您可以在单个管道中执行所有 transformation/manipulation 和重塑代码,而无需创建 x_agg_histx_agg_hist_agg_sum 等中间变量。所以你不必 remember/manage 他们。

你代码的前几步代码可以翻译为:

library(dplyr)

x %>%
  group_by(strand, name) %>%
  summarise(res = hist(value, breaks = seq(0.5, 6.5),plot= FALSE)$counts) %>%
  left_join(y, by = 'name') %>%
  mutate(division = factor(ifelse(value > 0.5, 1, 2)))  %>%
  ungroup 

使用 pivot_wider 将数据转换为宽格式,这将保留数据的名称。