重复循环有零替换
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"
我正在尝试编写一个循环,将组 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"