【问题标题】:Nested For loops in R not giving the desired outputR中的嵌套For循环没有给出所需的输出
【发布时间】:2021-01-13 16:34:15
【问题描述】:

您好,我正在使用嵌套的 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

如果我的问题很长,我提前道歉,我只是想确保我解释得很好。 提前感谢您的帮助。

【问题讨论】:

    标签: r for-loop nested-loops


    【解决方案1】:

    您只需要两个合并和一个中间数据帧:

    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)https://stackoverflow.com/a/6188334/3358272 来了解连接(它们是一种非常强大的数据操作机制!),并考虑使用dplyrdata.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]
    

    【讨论】:

    • 非常感谢@r2evans!那是那么干净和功效。我真的很喜欢你使用的left_join 函数,它可以帮助我处理很多其他匹配的数据集。
    • 我发现合并/连接的概念一开始都是陌生的,然后当你开始理解它并能够利用它时,它就会变得非常强大。然后它变得很自然,你想知道没有它你是如何生存的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-17
    • 1970-01-01
    • 2019-04-05
    相关资源
    最近更新 更多