结合ifelse语句和for循环R
我有关于某人是否被一系列学校(1至35所)录取的数据,以及他们对这些学校的偏好。我的数据集最终会有更多的学生和学校,但这是一个模拟数据集,可以做一些尝试工作。数据如下所示,但也会有更多的学校:结合ifelse语句和for循环R,r,for-loop,if-statement,R,For Loop,If Statement,我有关于某人是否被一系列学校(1至35所)录取的数据,以及他们对这些学校的偏好。我的数据集最终会有更多的学生和学校,但这是一个模拟数据集,可以做一些尝试工作。数据如下所示,但也会有更多的学校: > head(Schools) ID S1_AR S1_Rank S2_AR S2_Rank 1 ID001 Provisional Accept 1 Provisional Accept 2 2 ID002 Pr
> 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
Schools$Match这是一个真正的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
##数据集
df查看dplyr::case\u时的。看来这就是你需要的。谢谢你,哈利,这真是太有用了!只需注意一个小的输入错误,行ifelse(tmp$ck_2[i]==TRUE,decision[i]