查找所有可能的列组合的总和而不重复
Finding sum of all possible column combinations without repetition
我有一个大的 table 结构如下:
DT <- data.table(Sample = c(LETTERS[1:3]),
ColA = c(1:3),
ColB = c(3:1),
ColC = 1,
ColD = 2)
> DT
Sample ColA ColB ColC ColD
1: A 1 3 1 2
2: B 2 2 1 2
3: C 3 1 1 2
我希望找到 3 列的所有可能的非重复组合,然后找到每个样本在这些列中的值的总和。
所需的输出如下所示。
Sample FirstCol SecondCol ThirdCol SumOfCols
1: A ColA ColB ColC 5
2: A ColA ColB ColD 6
3: A ColA ColC ColD 4
4: A ColB ColC ColD 6
5: B ColA ColB ColC 5
6: B ColA ColB ColD 6
7: B ColA ColC ColD 5
8: B ColB ColC ColD 5
9: C ColA ColB ColC 5
10: C ColA ColB ColD 6
11: C ColA ColC ColD 6
12: C ColB ColC ColD 4
目前,我正在使用 combn() 查找列的所有组合,然后我通过使用 merge() 三次(对组合中的每个列一次)将值附加到它。
Combinations <- combn(colnames(DT[,!1]), 3)
Combinations <- as.data.table(t(Combinations))
lapply(DT$Sample, function(i){
Melted <- as.data.table(melt(DT[Sample == i], id.vars = "Sample"))[,!1]
Output <- merge(Combinations, Melted, by.x="V1", by.y="variable")
Output <- merge(Output, Melted, by.x="V2", by.y="variable")
Output <- merge(Output, Melted, by.x="V3", by.y="variable")
colnames(Output) <- c("ThirdCol", "SecondCol", "FirstCol", "FirstValue", "SecondValue","ThirdValue")
Output$SumOfCols <- Output$FirstValue + Output$SecondValue + Output$ThirdValue
Output$Sample <- i
Output <- Output[,c(8,3,2,1,7)]
})
虽然这达到了我想要的效果,但速度很慢,因为我的真实数据集相当大。我想知道是否有人可以告诉我如何加快速度。
如有任何帮助,我们将不胜感激,
谢谢!
DT %>%
group_by(Sample) %>%
summarise(s = combn(cur_data(), 3, \(x)c(nms = names(x), Sum = rowSums(x)),
simplify = FALSE), .groups = 'drop') %>%
unnest_wider(s) %>%
type.convert(as.is = TRUE)
# A tibble: 12 x 5
Sample nms1 nms2 nms3 Sum
<chr> <chr> <chr> <chr> <int>
1 A ColA ColB ColC 5
2 A ColA ColB ColD 6
3 A ColA ColC ColD 4
4 A ColB ColC ColD 6
5 B ColA ColB ColC 5
6 B ColA ColB ColD 6
7 B ColA ColC ColD 5
8 B ColB ColC ColD 5
9 C ColA ColB ColC 5
10 C ColA ColB ColD 6
11 C ColA ColC ColD 6
12 C ColB ColC ColD 4
我有一个大的 table 结构如下:
DT <- data.table(Sample = c(LETTERS[1:3]),
ColA = c(1:3),
ColB = c(3:1),
ColC = 1,
ColD = 2)
> DT
Sample ColA ColB ColC ColD
1: A 1 3 1 2
2: B 2 2 1 2
3: C 3 1 1 2
我希望找到 3 列的所有可能的非重复组合,然后找到每个样本在这些列中的值的总和。
所需的输出如下所示。
Sample FirstCol SecondCol ThirdCol SumOfCols
1: A ColA ColB ColC 5
2: A ColA ColB ColD 6
3: A ColA ColC ColD 4
4: A ColB ColC ColD 6
5: B ColA ColB ColC 5
6: B ColA ColB ColD 6
7: B ColA ColC ColD 5
8: B ColB ColC ColD 5
9: C ColA ColB ColC 5
10: C ColA ColB ColD 6
11: C ColA ColC ColD 6
12: C ColB ColC ColD 4
目前,我正在使用 combn() 查找列的所有组合,然后我通过使用 merge() 三次(对组合中的每个列一次)将值附加到它。
Combinations <- combn(colnames(DT[,!1]), 3)
Combinations <- as.data.table(t(Combinations))
lapply(DT$Sample, function(i){
Melted <- as.data.table(melt(DT[Sample == i], id.vars = "Sample"))[,!1]
Output <- merge(Combinations, Melted, by.x="V1", by.y="variable")
Output <- merge(Output, Melted, by.x="V2", by.y="variable")
Output <- merge(Output, Melted, by.x="V3", by.y="variable")
colnames(Output) <- c("ThirdCol", "SecondCol", "FirstCol", "FirstValue", "SecondValue","ThirdValue")
Output$SumOfCols <- Output$FirstValue + Output$SecondValue + Output$ThirdValue
Output$Sample <- i
Output <- Output[,c(8,3,2,1,7)]
})
虽然这达到了我想要的效果,但速度很慢,因为我的真实数据集相当大。我想知道是否有人可以告诉我如何加快速度。
如有任何帮助,我们将不胜感激, 谢谢!
DT %>%
group_by(Sample) %>%
summarise(s = combn(cur_data(), 3, \(x)c(nms = names(x), Sum = rowSums(x)),
simplify = FALSE), .groups = 'drop') %>%
unnest_wider(s) %>%
type.convert(as.is = TRUE)
# A tibble: 12 x 5
Sample nms1 nms2 nms3 Sum
<chr> <chr> <chr> <chr> <int>
1 A ColA ColB ColC 5
2 A ColA ColB ColD 6
3 A ColA ColC ColD 4
4 A ColB ColC ColD 6
5 B ColA ColB ColC 5
6 B ColA ColB ColD 6
7 B ColA ColC ColD 5
8 B ColB ColC ColD 5
9 C ColA ColB ColC 5
10 C ColA ColB ColD 6
11 C ColA ColC ColD 6
12 C ColB ColC ColD 4