我有关于某人是否被某所学校(1到35)录取以及他们对这些学校有偏好的数据。我的数据集最终将有更多的学生和学校,但这是一个模拟数据集,可以用来做一些跟踪工作。数据看起来像这样,但还将有更多的学校:
> head(Schools)
ID S1_AR S1_Rank S2_AR S2_Rank
1 ID001 Provisional Accept 1 Provisional Accept 2
2 ID002 Provisional Accept 1 No Application NA
3 ID003 Provisional Reject 1 Provisional Accept 2
4 ID004 Provisional Reject 2 Provisional Accept 1
5 ID005 Provisional Accept 3 Provisional Accept 1
每个人最多只能上一所学校,因此,如果他们被多于一所学校临时录取,则他们的择优排名最低的学校将被视为不接受。这意味着他们的位置可以供其他学生使用。
我已经编写了代码,用于识别已被学校1和2录取的学生,比较其排名,并更新其录取状态,如下所示。但是,这仅适用于一对学校,而我将需要为35所不同学校中的每对学校这样做。是否可以使用for循环针对不同的学校对自动执行此过程?
此外,我知道我的代码目前很笨拙,但这是我目前使用它的唯一方法。使用嵌套的ifelse()是否有助于使此代码在for循环中更易于管理?
Schools$Match <-ifelse(Schools$S1_AR == "Provisional Accept" & Schools$S2_AR == "Provisional Accept", 1, 0)
Schools$Preference<- ifelse(Schools$S1_Rank<Schools$S2_Rank, 1,2)
Schools$S2_AR[Schools$Match == 1 & Schools$Preference == 1]<- "Accepted Elsewhere"
Schools$S1_AR[Schools$Match == 1 & Schools$Preference == 2]<- "Accepted Elsewhere"
head(Schools)
ID S1_AR S1_Rank S2_AR S2_Rank Match Preference
1 ID001 Provisional Accept 1 Accepted Elsewhere 2 1 1
2 ID002 Provisional Accept 1 No Application NA 0 NA
3 ID003 Provisional Reject 1 Provisional Accept 2 0 1
4 ID004 Provisional Reject 2 Provisional Accept 1 0 2
5 ID005 Accepted Elsewhere 3 Provisional Accept 1 1 2
答案 0 :(得分:0)
这是一个真正的hacky功能,但是只要数据集看起来像您提供的那样,它就可以为任意数量的学校使用。基本上,它执行以下操作:
制作一个临时数据集,并添加一个变量,以检查学生是否已在多所学校“接受”,这意味着需要根据选择的等级做出决定(根据您的描述,如果我理解是对的)。
接下来,它生成2个索引向量。这些索引将用于提取由于默认(无选择)而选择或由于排名而选择的列名或学校。
根据逻辑检查生成学校名称的向量。如果需要做出选择,则等级最低的学校名称将添加到学生所在位置的向量中,如果不需要做出决定,则将添加学生接受的学校。我这样做的目的是,在任何情况下都有学生接受不是首选的学校(请参阅示例数据中的第6行)。
就像@ slava-kohut指出的那样,可能有一种更优雅的方法来完成所有这些工作,如果可以的话,值得研究。
这是函数。我希望这会有所帮助:
## data set
df <- data.frame("ID" = 1:6,
"S1_AR" = c("PA", "PA", "PR", "PR", "PA", "PA"),
"S1_Rank" = c(1, 1, 1, 2, 3, 2),
"S2_AR" = c("PA", "NA", "PA", "PA", "PA", "PR"),
"S2_Rank" = c(2, NA, 2, 1, 1, 1))
my_fun <- function(data){
## generate tmp data and ready data for downstream classification
tmp <- data %>%
mutate(ck_1 = rowSums(. == "PA"),
ck_2 = ifelse(ck_1 > 1, TRUE, FALSE),
ck_2 = ifelse(is.na(ck_2), FALSE, ck_2))
## generate rank table
tmp.rank <- tmp %>%
dplyr::select(contains("_Rank"))
## generate choice table
tmp.ar <- tmp %>%
dplyr::select(contains("_AR"))
## generate index of highest ranked school choice
index_choose <- apply(tmp[, which(colnames(tmp) %in% colnames(tmp.rank))], 1,
function(x){
which.min(x)
})
## generate index for school accepted when no choice needs to be made
index_nochoose <- sapply(apply(tmp[, which(colnames(tmp) %in%
colnames(tmp.ar))], 1, function(x){
which(x == "PA")
}), function(a) a[[1]])
## Generate decision vector
decision <- c()
for(i in 1:nrow(df)){
ifelse(tmp$ck_2[i] == TRUE, decision[i] <- colnames(tmp.rank)
[index_choose[i]],
decision[i] <- colnames(tmp.ar)[index_nochoose[i]])
}
decision <- sapply(strsplit(decision, split = "_", fixed = TRUE),
function(x)
x[1])
## add vector and output result
tmp$decision <- decision
return(tmp)
}
my_fun(df)
ID S1_AR S1_Rank S2_AR S2_Rank ck_1 ck_2 decision
1 1 PA 1 PA 2 2 TRUE S1
2 2 PA 1 NA NA NA FALSE S1
3 3 PR 1 PA 2 1 FALSE S2
4 4 PR 2 PA 1 1 FALSE S2
5 5 PA 3 PA 1 2 TRUE S2
6 6 PA 2 PR 1 1 FALSE S1