重复循环有零替换

repeat loop has zero replacements

我正在尝试编写一个循环,将组 DT/DF 中的 'middle' 值与其前面的列进行比较。当循环遇到一个值大于相应 'middle' 列值的列时,将该列名称打印到一个名为 mIncome 的向量中,并跳过剩余的列并继续循环中的下一次迭代。然而,循环似乎并没有结束。

我最终想要一个向量,其中包含第一列的名称,其值大于相应行的 'middle' 值。我知道不推荐循环,但如果有人有任何建议...

groups <- dput(groups)
structure(list(one = c(33, 32, 161, 93, 69, 74, 24, 24, 21, 25
), two = c(53, 68, 164, 111, 96, 125, 35, 103, 39, 25), three = c(109, 
97, 188, 159, 160, 169, 53, 149, 106, 34), four = c(114, 161, 
214, 183, 302, 190, 86, 193, 155, 62), five = c(120, 183, 237, 
241, 384, 257, 105, 388, 174, 62), six = c(169, 269, 264, 262, 
633, 293, 195, 489, 239, 122), seven = c(209, 351, 351, 279, 
717, 326, 243, 652, 291, 152), eight = c(214, 393, 357, 346, 
769, 336, 255, 672, 353, 197), nine = c(238, 459, 365, 364, 816, 
336, 336, 722, 363, 197), middle = c(119, 230, 182, 182, 408, 
168, 168, 361, 182, 98)), .Names = c("one", "two", "three", "four", 
"five", "six", "seven", "eight", "nine", "middle"), class = c("data.table", 
"data.frame"), row.names = c(NA, -10L), .internal.selfref = <pointer: 0x00000000000b0788>)




repeat{
   mIncome <- character(length = nrow(groups))

for(i in 1:(dim(groups)[1])){
   for(j in 1:(dim(groups)[2] - 1)){
      if(groups[i][[10]] < groups[i][[j]]){ # is middle value greater than...
         mIncome[i] <- as.character(colnames(groups[, j - 1, with = FALSE]))
         break
         } else (print('no')) 
      } 
    }
   mIncome
}

我刚刚添加了 medclass[,j,with=FALSE],这应该可以解决您的问题。这是一个解决方案

for(i in 1:(dim(medclass)[1])){
  for(j in 1:(dim(medclass)[2] - 1)){
    if(groups[i][[10]] > groups[i][[j]]){ # is middle value greater than...
      mIncome[i] <- as.character(colnames(medclass[, j,with=FALSE]))
      next
    } else (print('no')) 
  }
}

具有正确索引的解决方案:

for(i in 1:(dim(medclass)[1])){
  for(j in 1:(dim(medclass)[2] - 3)){
    if(groups[i][[10]] > groups[i][[j]]){ # is middle value greater than...
      mIncome[i] <- as.character(colnames(medclass[, j+4,with=FALSE]))
      next
    } else (print('no')) 
  }
}

这绝不是一个有效的解决方案。必须有一个有效的解决方案。

几个问题。一,在文中你说

When the loop comes across a column that has a value larger than corresponding 'middle' column value

但在您的代码中,您有

if(groups[i][[10]] > groups[i][[j]]){ # is middle value greater than...

所以,你想要值大于中间值的地方,还是中间值大于值的地方?

其次,当您发现自己使用多个嵌套 for 循环时,可能有更简单的方法。

我将首先创建一个函数,然后将其应用于每一行。

appfunc <- function(x) {
  if (!any(x[1:(length(x)-1)] > x[length(x)])) return("no")
  names(groups)[which(x[1:(length(x)-1)] > x[length(x)])[1]]
}

让我们打开包装。该函数将从 data.frame 传递行 x,在这种情况下,我假设 groups data.frame。对于数据集中的第一行,x 将为 c(33, 55, 109, 114, 120, 169, 209, 214, 238, 119)。函数中的第一行检查除最后​​一个元素之外的 x 的任何值是否大于最后一个元素,如果不是 return "no"。如果至少有一个值更大,则第二行将 return 第一行,并且 return 该列的相应名称。

因此,对于 groups 中的第一行,我们希望函数 return "five".

现在,让 apply 函数到 groups 的每一行。

apply(groups, 1, appfunc)

这里的语法非常简单。这只是说将我们上面定义的 appfunc 应用到 groups 中的每一行。

输出:

# [1] "five"  "six"   "three" "four"  "six"   "three" "six"   "five"  "six"   "six"