data.table 中的多个列相对于另一列中的值

Bin multiple columns in a data.table with respect to values in another column

我有一个有 N=3 列的 data.table。为简单起见,我们假设第一列是预期值,后续列是每个样本中对该特定值的观察。

data.table示例:

experiment obs_s1 obs_s2
1 1 1
2 2 2
3 3 3
4 2 2
5 2 4
6 4 4
7 5 4
8 4 4
9 3 3
10 4 4

挑战在于将实验分为任意间隔,并将特定函数应用于样本观察。让我们假设,找到自定义范围内所有观测值的最大值和总和。

由于制作新的 data.table 代码看起来很复杂,所以我首先使用 melt.data.table:

experiment sample count
1   obs_s1  1
2   obs_s1  2
3   obs_s1  3
4   obs_s1  2
5   obs_s1  2
6   obs_s1  4
7   obs_s1  5
8   obs_s1  4
9   obs_s1  3
10  obs_s1  4
1   obs_s2  1
2   obs_s2  2
3   obs_s2  3
4   obs_s2  2
5   obs_s2  4
6   obs_s2  4
7   obs_s2  4
8   obs_s2  4
9   obs_s2  3
10  obs_s2  4

并尝试使用 cut,但这仅适用于 count 的一列,但我无法真正应用具有 lapply 或类似于输出的函数。示例:

experiment = c(0,4,8,10)
labels = c('bin_1', 'bin_2', 'bin_3')
my_dt_melt <- my_dt_melt[, bins":= cut(insert_size, breaks = insert_size_intervals, labels = labels)]

我现在所做的只是使用 for 循环并提取值并创建一个新的 data.table,但它并没有利用 data.table

的强大功能

我想从这个融化的 data.table 中获得的输出如下:

  1. 最大值输出示例:
range sample value
1-4 obs_s1 3
1-4 obs_s2 3
5-8 obs_s1 5
5-8 obs_s2 4
9-10 obs_s1 4
9-10 obs_s2 4
  1. 值总和的示例输出:
range sample value
1-4 obs_s1 8
1-4 obs_s2 8
5-8 obs_s1 15
5-8 obs_s2 16
9-10 obs_s1 7
9-10 obs_s2 7

所以问题是:如何将融化的 data.table w.r.t 中的列分箱到第一列并对其应用函数?

您可以将 functions/expressions 放在 by 参数中:

my_dt_melt[, list(maxcount = max(count), sumcount = sum(count)),
   by = .(
     range = cut(
       experiment,
       c(0,4,8,10),
       labels = c('bin_1', 'bin_2', 'bin_3')),
     sample
)]
#      range sample maxcount sumcount
# 1:   bin_1 obs_s1        3        8
# 2:   bin_2 obs_s1        5       15
# 3:   bin_3 obs_s1        4        7
# 4:   bin_1 obs_s2        3        8
# 5:   bin_2 obs_s2        4       16
# 6:   bin_3 obs_s2        4        7