R 中的嵌套 For 循环未提供所需的输出
Nested For loops in R not giving the desired output
您好,我正在使用嵌套 for 循环在两个数据集中查找兼容的血型。
我的数据集:
#IDR= c(seq(1,4))
#BTR=c("A","B","AB","O")
#data_R=data.frame(IDR,BTR,stringsAsFactors=FALSE)
#IDD= c(seq(1,8))
#BTD= c(rep("A", each=2),rep("B", each=2),rep("AB", each=2),rep("O", each=2))
#WD= c(rep(0.25, each=2),rep(0.125, each=2),rep(0.125, each=2),rep(0.5, each=2))
#data_D=data.frame(IDD,BTD,WD,stringsAsFactors=FALSE)
# data_R
IDR BTR
1 1 A
2 2 B
3 3 AB
4 4 O
# data_D
IDD BTD WD
1 1 A 0.250
2 2 A 0.250
3 3 B 0.125
4 4 B 0.125
5 5 AB 0.125
6 6 AB 0.125
7 7 O 0.500
8 8 O 0.500
我想做的是验证 data_R 的每一行我在 data_D 中的血型是否兼容,例如:
如果我有 BTR=AB 那么我想在 data_D 中打印 WD 的所有值(因为 AB 与 A、B、AB 和 O 兼容),
如果我有 BTR=A 那么我想在 data_D 中打印仅对应于 A 和 O 的 WD 值,
如果我有 BTR=B 那么我想在 data_D 中打印仅对应于 B 和 O 的 WD 值,
最后,如果我有 BTR=O 那么我只想打印 data_D 中对应于 O.
的 WD 值
这是我写的代码,但输出没有我想要的结果
for (i in 1:nrow(data_R)) {
for (j in 1:nrow(data_D)) {
if(BTR[i] =="AB"){
if(BTD[j]=="A" || BTD[j]=="B" || BTD[j]=="AB" || BTD[j]=="O"){
output=as.vector(WD)
}
}else if(BTR[i] =="A"){
if(BTD[j]=="A" || BTD[j]=="O"){
output=as.vector(WD)
}
}else if(BTR[i] =="B"){
if(BTD[j]=="B" || BTD[j]=="O"){
output=as.vector(WD)
}
}else if(BTR[i] =="O"){
if(BTD[j] =="O"){
output=as.vector(WD)
}
}
}
}
output
and that is the output i got: [1] 0.250 0.250 0.250 0.250 0.125 0.125 0.500 0.500
我只能得到输出(错误),如果能帮助解决这个问题并显示更易读(从两个数据集中获取信息)的输出,我将不胜感激:
BTR BTD output
1 A A 0.250
2 A A 0.250
3 A O 0.500
4 A O 0.500
5 B B 0.125
6 B B 0.125
7 B O 0.500
8 B O 0.500
9 AB A 0.250
10 AB A 0.250
11 AB B 0.125
12 AB B 0.125
13 AB AB 0.125
14 AB AB 0.125
15 AB O 0.500
16 AB O 0.500
17 O O 0.500
18 O O 0.500
如果我的问题很长,我提前道歉,我只是想确保我解释得很好。
预先感谢您的帮助。
你只需要两个合并和一个中间 data.frame:
compatible <- data.frame(
BTR = c(rep("AB", 4), rep("A", 2), rep("B", 2), "O"),
BTD = c("AB","A","B","O", "A","O", "B","O", "O")
)
compatible
# BTR BTD
# 1 AB AB
# 2 AB A
# 3 AB B
# 4 AB O
# 5 A A
# 6 A O
# 7 B B
# 8 B O
# 9 O O
第一步为每位接受者提供所有可能个捐赠者:
tmp <- merge(data_R, compatible, by = "BTR", all.x = TRUE, sort = FALSE)
tmp
# BTR IDR BTD
# 1 A 1 A
# 2 A 1 O
# 3 B 2 B
# 4 B 2 O
# 5 AB 3 AB
# 6 AB 3 A
# 7 AB 3 B
# 8 AB 3 O
# 9 O 4 O
第二次合并带来了可用的捐助者:
merge(tmp, data_D, by = "BTD")
# BTD BTR IDR IDD WD
# 1 A A 1 1 0.250
# 2 A A 1 2 0.250
# 3 A AB 3 1 0.250
# 4 A AB 3 2 0.250
# 5 AB AB 3 5 0.125
# 6 AB AB 3 6 0.125
# 7 B B 2 3 0.125
# 8 B B 2 4 0.125
# 9 B AB 3 3 0.125
# 10 B AB 3 4 0.125
# 11 O B 2 7 0.500
# 12 O B 2 8 0.500
# 13 O O 4 7 0.500
# 14 O O 4 8 0.500
# 15 O A 1 7 0.500
# 16 O A 1 8 0.500
# 17 O AB 3 7 0.500
# 18 O AB 3 8 0.500
请注意,顺序不同,但其中包含您预期的输出。
虽然这是使用基础 R,但其他包提供了对合并的更多控制。我建议您查看 How to join (merge) data frames (inner, outer, left, right) and 以了解连接(它们是一种非常强大的 data-manipulation 机制!),并考虑使用 dplyr
或 data.table
来促进此流程:
library(dplyr)
left_join(data_R, compatible, by = "BTR") %>%
left_join(data_D, by = "BTD")
library(data.table)
data_RDT <- as.data.table(data_R)
data_DDT <- as.data.table(data_D)
compatible <- as.data.table(compatible)
compatible[data_RDT, on = .(BTR)][data_DDT, on = .(BTD), allow.cartesian = TRUE]
您好,我正在使用嵌套 for 循环在两个数据集中查找兼容的血型。 我的数据集:
#IDR= c(seq(1,4))
#BTR=c("A","B","AB","O")
#data_R=data.frame(IDR,BTR,stringsAsFactors=FALSE)
#IDD= c(seq(1,8))
#BTD= c(rep("A", each=2),rep("B", each=2),rep("AB", each=2),rep("O", each=2))
#WD= c(rep(0.25, each=2),rep(0.125, each=2),rep(0.125, each=2),rep(0.5, each=2))
#data_D=data.frame(IDD,BTD,WD,stringsAsFactors=FALSE)
# data_R
IDR BTR
1 1 A
2 2 B
3 3 AB
4 4 O
# data_D
IDD BTD WD
1 1 A 0.250
2 2 A 0.250
3 3 B 0.125
4 4 B 0.125
5 5 AB 0.125
6 6 AB 0.125
7 7 O 0.500
8 8 O 0.500
我想做的是验证 data_R 的每一行我在 data_D 中的血型是否兼容,例如: 如果我有 BTR=AB 那么我想在 data_D 中打印 WD 的所有值(因为 AB 与 A、B、AB 和 O 兼容), 如果我有 BTR=A 那么我想在 data_D 中打印仅对应于 A 和 O 的 WD 值, 如果我有 BTR=B 那么我想在 data_D 中打印仅对应于 B 和 O 的 WD 值, 最后,如果我有 BTR=O 那么我只想打印 data_D 中对应于 O.
的 WD 值这是我写的代码,但输出没有我想要的结果
for (i in 1:nrow(data_R)) {
for (j in 1:nrow(data_D)) {
if(BTR[i] =="AB"){
if(BTD[j]=="A" || BTD[j]=="B" || BTD[j]=="AB" || BTD[j]=="O"){
output=as.vector(WD)
}
}else if(BTR[i] =="A"){
if(BTD[j]=="A" || BTD[j]=="O"){
output=as.vector(WD)
}
}else if(BTR[i] =="B"){
if(BTD[j]=="B" || BTD[j]=="O"){
output=as.vector(WD)
}
}else if(BTR[i] =="O"){
if(BTD[j] =="O"){
output=as.vector(WD)
}
}
}
}
output
and that is the output i got: [1] 0.250 0.250 0.250 0.250 0.125 0.125 0.500 0.500
我只能得到输出(错误),如果能帮助解决这个问题并显示更易读(从两个数据集中获取信息)的输出,我将不胜感激:
BTR BTD output
1 A A 0.250
2 A A 0.250
3 A O 0.500
4 A O 0.500
5 B B 0.125
6 B B 0.125
7 B O 0.500
8 B O 0.500
9 AB A 0.250
10 AB A 0.250
11 AB B 0.125
12 AB B 0.125
13 AB AB 0.125
14 AB AB 0.125
15 AB O 0.500
16 AB O 0.500
17 O O 0.500
18 O O 0.500
如果我的问题很长,我提前道歉,我只是想确保我解释得很好。 预先感谢您的帮助。
你只需要两个合并和一个中间 data.frame:
compatible <- data.frame(
BTR = c(rep("AB", 4), rep("A", 2), rep("B", 2), "O"),
BTD = c("AB","A","B","O", "A","O", "B","O", "O")
)
compatible
# BTR BTD
# 1 AB AB
# 2 AB A
# 3 AB B
# 4 AB O
# 5 A A
# 6 A O
# 7 B B
# 8 B O
# 9 O O
第一步为每位接受者提供所有可能个捐赠者:
tmp <- merge(data_R, compatible, by = "BTR", all.x = TRUE, sort = FALSE)
tmp
# BTR IDR BTD
# 1 A 1 A
# 2 A 1 O
# 3 B 2 B
# 4 B 2 O
# 5 AB 3 AB
# 6 AB 3 A
# 7 AB 3 B
# 8 AB 3 O
# 9 O 4 O
第二次合并带来了可用的捐助者:
merge(tmp, data_D, by = "BTD")
# BTD BTR IDR IDD WD
# 1 A A 1 1 0.250
# 2 A A 1 2 0.250
# 3 A AB 3 1 0.250
# 4 A AB 3 2 0.250
# 5 AB AB 3 5 0.125
# 6 AB AB 3 6 0.125
# 7 B B 2 3 0.125
# 8 B B 2 4 0.125
# 9 B AB 3 3 0.125
# 10 B AB 3 4 0.125
# 11 O B 2 7 0.500
# 12 O B 2 8 0.500
# 13 O O 4 7 0.500
# 14 O O 4 8 0.500
# 15 O A 1 7 0.500
# 16 O A 1 8 0.500
# 17 O AB 3 7 0.500
# 18 O AB 3 8 0.500
请注意,顺序不同,但其中包含您预期的输出。
虽然这是使用基础 R,但其他包提供了对合并的更多控制。我建议您查看 How to join (merge) data frames (inner, outer, left, right) and 以了解连接(它们是一种非常强大的 data-manipulation 机制!),并考虑使用 dplyr
或 data.table
来促进此流程:
library(dplyr)
left_join(data_R, compatible, by = "BTR") %>%
left_join(data_D, by = "BTD")
library(data.table)
data_RDT <- as.data.table(data_R)
data_DDT <- as.data.table(data_D)
compatible <- as.data.table(compatible)
compatible[data_RDT, on = .(BTR)][data_DDT, on = .(BTD), allow.cartesian = TRUE]