gpt4 book ai didi

重新排列观察结果以达到所需值 - data.table?

转载 作者:行者123 更新时间:2023-12-04 12:19:12 25 4
gpt4 key购买 nike

我有一个包含多个观察值的数据表 - 每个观察值都有一个非唯一 ID 和整数 X 值。按 ID 分组。我希望每个组的 X 之和大于 10。为此,只要原始组的 X 之和不低于 10,就允许每个观察更改其 ID。

下面是我的意思的一个例子,也是一个非常手动的解决方案:

# sample data
input <-data.table(ID = c("A", "A", "A", "B", "B", "B" ,
"C", "C", "C", "D", "D", "D"),
X = c(1, 3, 1, 5, 1, 5,
6, 10, 2, 3, 3, 4))
# summarise X by ID
input[, .(X = sum(X)), by = ID]

ID X
A 5
B 11
C 18
D 10

# what the output should look like
output <- data.table(ID = c("A", "A", "A", "B", "B", "B" ,
"A", "C", "C", "D", "D", "D"),
X = c(1, 3, 1, 5, 1, 5,
6, 10, 2, 3, 3, 4))

output[, .(X = sum(X)), by = ID]

ID X
A 11
B 11
C 12
D 10

output

ID X
A 1
A 3
A 1
B 5
B 1
B 5
A 6 - this observation changed ID from C to A to get group A to 11
C 10
C 2

这显然是一个非常简单的例子,因为只有 C 组有足够的空闲能力来提供观察结果。实际上,可能存在这样的情况,多个组能够提供观察结果,并且必须修改多个观察结果,但是最多只能有 4 个组之间可以发生移动。

是否可以在 R 中自动执行此过程?

最佳答案

这是一种可能的启发式方法。首先,对小于或大于 10 的 ID 进行子集化(例如,这些 ID 有 N 个)。然后,将这些 ID 的值按降序分配到这 N 个桶中最小的一个。

b <- 10
input <- data.table(ID = c("A", "A", "A", "B", "B", "B", "C", "C", "C", "D", "D", "D"),
X = c(1, 3, 1, 5, 1, 5, 6, 10, 2, 3, 3, 4))

#find the IDs that need redistribution
scramID <- input[, sum(X), by = ID][V1!=b, ID]

#extract the values for those IDs
x <- input[ID %in% scramID, sort(X, decreasing=TRUE)]

#create list of empty vectors as buckets
l <- replicate(length(scramID), vector('integer'))

#assign the values starting with largest to the bucket with the smallest sum
for (k in x) {
i <- which.min(lapply(l, sum))
l[[i]] <- c(l[[i]], k)
}

#rbind to original dataset to get result
names(l) <- scramID
ans <- rbindlist(list(
setnames(setDT(stack(l)), c("X","ID")),
input[!ID %in% scramID]
), use.names=TRUE)

输出:

     X ID
1: 10 A
2: 1 A
3: 1 A
4: 6 B
5: 3 B
6: 2 B
7: 5 C
8: 5 C
9: 1 C
10: 3 D
11: 3 D
12: 4 D

以及值的分布:

> ans[, sum(X), by = ID]
ID V1
1: A 12
2: B 11
3: C 11
4: D 10

对于此示例,选择用于重新分配的 ID 是 A、B 和 C。共有三个存储桶。这些 ID 的值按降序排列为 10、6、5、5、3、2、1、1 和 1。

在前 3 次迭代中,分别将 10、6 和 5 分配给第一、第二和第三个桶。

下一个数字是 5,它被分配给编号为 5 的第三个桶,因为它具有三个桶中最小的总和 (5)。

下一个数字 3 分配给第二个桶,因为它具有三个桶中最小的总和 (6)。

其余数字依此类推。

关于重新排列观察结果以达到所需值 - data.table?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57957575/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com