【问题标题】:Nested For Loops w/ If-Else带有 If-Else 的嵌套 For 循环
【发布时间】:2018-07-08 14:55:41
【问题描述】:

我以前从未做过嵌套的 for 循环,而且我对 for 循环的理解也只是初步的。我试图让循环遍历矩阵的行,然后将向量的元素写入空矩阵。我也对非循环/矢量化解决方案持开放态度,尽管我很想知道为什么我的循环代码如此无望地被破坏。

设置输入矩阵和向量:

condition = c(0,1,2)
condition_risk = c(0,1,1,2,2,2)
condition_health = c(0,0,0,1,1,2)
ES = rnorm(n = 10)

ppt1 = matrix(sample(condition, 10, replace = T), ncol = 10, nrow = 100)
ppt2 = matrix(sample(condition_risk, 10, replace = T), ncol = 10, nrow = 25)
ppt3 = matrix(sample(condition_health, 10, replace = T), ncol = 10, nrow = 25)

key = rbind(ppt1,ppt2,ppt3)
key_recoded = matrix(NA, ncol = 10, nrow = 150)

这会创建一个名为“ES”的效果向量 -1 到 1;带有条件 0,1,2 的矩阵,称为“键”;和一个具有相同维度的空矩阵,称为“key_recoded”:

head(ES)
-0.31741374 -0.08023316 -0.57528823  0.78028852 -0.20937815  0.12266581

head(key)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    2    2    2    2    2    2    2    2    2     2
[2,]    0    0    0    0    0    0    0    0    0     0
[3,]    2    2    2    2    2    2    2    2    2     2
[4,]    0    0    0    0    0    0    0    0    0     0
[5,]    0    0    0    0    0    0    0    0    0     0
[6,]    2    2    2    2    2    2    2    2    2     2

head(key_recoded)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA
[2,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA
[3,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA
[4,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA
[5,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA
[6,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA

目标是在 ES 值为负数时将条件从 0,1,2 重新编码为 2,1,0。

例如,ES[1] = -.31741374 和 key[1,1] = 2,所以 key_recoded [1,1] 应该是 0 而不是 2。如果 key[1,1] 本来是 0,那么 key_recoded 将是 2 而不是 0。“key”中的条件值 1 将被忽略。

这就是 key_recoded 的样子;看到 0 和 2 从第一行的键 w/ 0s 而不是 2s 重新翻转:

head(key_recoded)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    0    0    0    0    0    0    0    0    0     0
[2,]    2    2    2    2    2    2    2    2    2     2
[3,]    0    0    0    0    0    0    0    0    0     0
[4,]    2    2    2    2    2    2    2    2    2     2
[5,]    0    0    0    0    0    0    0    0    0     0
[6,]    2    2    2    2    2    2    2    2    2     2

这是我可悲的代码,它对空矩阵“key_recoded”没有任何作用,但没有返回错误:

for (j in nrow(key)){
  for (i in nrow(ES)){
    if(ES[i] < 0 && key[j,i] == 2){
      key_recoded[j,i] = 0
    }
    else{
      key_recoded[j,i] = key[j,i]
    }
    if(ES[i] < 0 && key[j,i] == 0){
      key_recoded[j,i] = 2
    }
    else{
      key_recoded[j,i] = key[j,i]
    }
  }
}

【问题讨论】:

  • for (j in 1:nrow(key))。就像您拥有它一样,它只是最后一行。 i 索引也是如此。此外,nrow(ES) 返回NULL,因为ES 是一个向量,你应该使用length 或相当深奥的NROW
  • 请使用set.seed 使这些可重现
  • @RuiBarradas 哎呀。是的,这是个问题。我想我会留下它,因为解决方案代码解决了这个问题?
  • @rawr 抱歉,我不经常使用 set.seed。我无法让它每次都使随机的 012 相同。

标签: r for-loop if-statement nested


【解决方案1】:

我认为 Onyambu 的回答没有考虑 ES 是否为负值:

key2 <- key
for(i in 1:length(ES)){
  if(ES[i] < 0){
    key2[,i] <- ifelse(key2[,i] == 2, 0, ifelse(key2[,i] == 0, 2, key2[,i]))
  }
}
head(key)
head(key2)

【讨论】:

  • 是的,没错。当 ES 为负数时,它应该只交换 2s 和 0s。谢谢
【解决方案2】:
ES
 [1] -0.30114431 -0.97900009  1.04164231  0.64237371  0.44924653
 [6]  0.24134990 -0.20286873  0.49661435  0.30273617  0.05852534
 n=which(ES<0)
 key_recorded=key #Create a duplicate of key and store it in key_recorded
 key_recorded[,n][key[,n]==2]=0# Store 0 in key_recorded wherever key is 2
 key_recorded[,n][key[,n]==0]=2# Store 2 in key_recorded wherever key is 0
 head(key)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    0    0    0    0    0    0    0    0    0     0
[2,]    2    2    2    2    2    2    2    2    2     2
[3,]    0    0    0    0    0    0    0    0    0     0
[4,]    2    2    2    2    2    2    2    2    2     2
[5,]    1    1    1    1    1    1    1    1    1     1
[6,]    2    2    2    2    2    2    2    2    2     2
 head(key_recorded)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    2    2    0    0    0    0    2    0    0     0
[2,]    0    0    2    2    2    2    0    2    2     2
[3,]    2    2    0    0    0    0    2    0    0     0
[4,]    0    0    2    2    2    2    0    2    2     2
[5,]    1    1    1    1    1    1    1    1    1     1
[6,]    0    0    2    2    2    2    0    2    2     2

现在您可以看到,当 ES=0 时,所需的列会被翻转

【讨论】:

  • 对于初学者来说,将这些操作想象成这样可能会更有帮助: 对于key中值为2的每个位置,将key_recorded中的对应值设置为0。出于这里的目的,R 真的不关心 key_recorded 中的值是什么,所以说“替换”可能会让人感到困惑,即使这是由于第一次分配而最终发生的事情。
  • 我喜欢这样可以摆脱 for 循环,但它只需要在 ES 为负数时使用。我不能把所有的 0 换成 2。
  • 哦,也许我误解了你的问题。马上就会解决这个问题
  • 抱歉你用了nrow(ES)这个词,但是ES不是矩阵!!
  • @Onyambu 哇,这比循环好多了!你怎么知道它不需要?我正在尝试了解以备将来参考,以防将来遇到类似问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
相关资源
最近更新 更多