想象一下以下格式的 df:
ID1 ID2
1 A 1
2 A 2
3 A 3
4 A 4
5 A 5
6 B 1
7 B 2
8 B 3
9 B 4
10 B 5
11 C 1
12 C 2
13 C 3
14 C 4
15 C 5
問題是為 ID1 中的第一個唯一值隨機選擇一行,從資料集中洗掉相應的 ID2 值,從剩余的 ID2 值池中隨機選擇一個值作為第二個 ID1 值(即遞回),依此類推。
因此,例如,對于第一個 ID1 值,它會執行sample(1:5, 1),結果為 2。對于第二個 ID1 值,它會執行sample(c(1, 3:5), 1),結果為 3。對于第三個 ID1 值,它會執行sample(c(1, 4:5), 1),結果為 5。不可能發生沒有唯一 ID2 值可分配給特定 ID1 的情況。最后,結果應該具有類似的格式:
ID1 ID2
1 A 2
2 B 3
3 C 5
它應該足夠有效地處理相當大的資料集(ID1 中的數萬個唯一值和每個 ID2 中的數十萬個唯一值)。
我嘗試了多種方法來解決這個問題,但老實說,它們都沒有意義,而且可能只會造成混亂,所以我不會在這里分享它們。
樣本資料:
df <- data.frame(ID1 = rep(LETTERS[1:3], each = 5),
ID2 = rep(1:5, 3))
uj5u.com熱心網友回復:
我認為該演算法可以滿足您的要求,但效率不高。它可以為其他人提供更快解決方案的起點。
all_ID1 <- unique(df$ID1)
available <- unique(df$ID2)
new_ID2 <- numeric(length(all_ID1))
for(i in seq_along(all_ID1))
{
ID2_group <- df$ID2[df$ID1 == all_ID1[i]]
sample_space <- ID2_group[ID2_group %in% available]
new_ID2[i]<- sample(sample_space, 1)
available <- available[available != new_ID2[i]]
}
data.frame(ID1 = all_ID1, ID2 = new_ID2)
#> ID1 ID2
#> 1 A 5
#> 2 B 1
#> 3 C 2
請注意,如果您用完唯一 ID2 值,這將不起作用。例如,如果 ID1 列中有字母 A:F,每個字母的 ID2 值為 1:5,那么當您開始為 ID1 值“F”選擇 ID2 值時,沒有唯一的 ID2 值了,因為數字 1 到 5 都已分配給字母 A:E。您沒有在問題中說明當沒有唯一的 ID2 值可以分配給特定的 ID1 時會發生什么 - 它們應該是NA,還是允許重復?
由reprex 包( v2.0.0 )于 2021 年 11 月 3 日創建
uj5u.com熱心網友回復:
selected <- c()
for(i in unique(df[,1])) {
x <- df[df[,"ID1"]==i,"ID2"]
y <- setdiff(x,selected)
selected <- unique(c(sample(y,1),selected))
}
data.frame(ID1 = unique(df[,1]), ID2 =selected)
給,
ID1 ID2
1 A 4
2 B 2
3 C 3
uj5u.com熱心網友回復:
一種可能的方法
library(data.table)
setDT(df)
exclude.values <- as.numeric()
L <- split(df, by = "ID1")
ans <- lapply(L, function(x) {
sample.value <- sample(setdiff(x$ID2, exclude.values), 1)
exclude.values <<- c(exclude.values, sample.value)
return(sample.value)
})
uj5u.com熱心網友回復:
您可以嘗試下面的代碼(Reduce應用于遞回添加未訪問的ID2值)
lst <- split(df, ~ID1)
Reduce(
function(x, y) {
y <- subset(y,!ID2 %in% x$ID2)
rbind(x, y[sample(nrow(y), 1), ])
},
lst[-1],
init = lst[[1]][sample(1:nrow(lst[[1]]), 1), ],
)
這使
ID1 ID2
4 A 4
7 B 2
11 C 1
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/346478.html
