我正在尝试编写一个比较'中间'从DT / DF组到其前一列的值。当循环遇到一个值大于相应“中间”的列时。列值,将该列名称打印到名为mIncome的向量,并跳过其余列并继续循环中的下一次迭代。但是,循环似乎没有结束。
我最终想要一个包含第一列名称的向量,其值大于'中间'相应行的值。我知道循环不推荐,但如果有人有任何建议......
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
}
答案 0 :(得分:1)
我刚刚添加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'))
}
}
绝不是一个有效的解决方案。必须有一个有效的解决方案。
答案 1 :(得分:1)
一些问题。一,在你说的文字中
当循环遇到值大于的列时 相应的中间&#39;列值
但在您的代码中,您有
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]]
}
让我们打开它。该函数将从x
的{{1}}行传递,在这种情况下,我假设data.frame
groups
。对于数据集中的第一行,x将为data.frame
。函数的第一行是检查除最后一个元素之外的x的任何值是否大于最后一个元素,如果不是,则返回&#34; no&#34;。如果至少有一个值更大,则第二行将返回第一行,并返回该列的相应名称。
因此,对于c(33, 55, 109, 114, 120, 169, 209, 214, 238, 119)
中的第一行,我们希望函数返回&#34;五&#34;。
现在,让groups
的每一行都有apply
函数。
groups
这里的语法非常简单。这只是说将上面定义的apply(groups, 1, appfunc)
应用于appfunc
中的每一行。
输出:
groups