我正在尝试编写一个脚本,如果找到数据匹配,则会跳过接下来的两次迭代。 对于一次迭代,我可以使用" next"命令,但这对于跳过几次迭代并不起作用。
这是我的剧本。
rowsToDelete<-c()
for(o in 1:nrow(data)){
if(data$reactionTime[o]>2000||data$V8[o]<9999){
rowsToDelete<-rbind(rowsToDelete,TRUE,TRUE,TRUE)
o<-o+2
}
else{
rowsToDelete<-rbind(rowsToDelete,FALSE)
}
}
我只是想弄清楚为什么if循环中o<-o+2
的部分没有跳过接下来的两次迭代,它只是将迭代量从13000扩大到14430(不同之处在于不良情况的数量)我的数据时间2)。
答案 0 :(得分:1)
我建议您自己使用repeat
和break
管理自己的计数器:
rowsToDelete<-c()
o<-1
repeat{
if(data$reactionTime[o]>2000||data$V8[o]<9999){
rowsToDelete<-rbind(rowsToDelete,TRUE,TRUE,TRUE)
o<-o+2
}
else{
rowsToDelete<-rbind(rowsToDelete,FALSE)
o<-o+1
}
if (o == nrow(data)) break
}
答案 1 :(得分:1)
R在两个方面的运作方式不同。
for
循环不能像这样工作 - 您无法修改循环变量,因为您已经注意到了自己。此外,您通常不会迭代索引,而是直接遍历元素。
要从矢量/矩阵/ data.frame中选择或删除特定对象,只需通过数字或逻辑索引选择这些元素即可。您的代码已朝这个方向发展,但您正在迭代地构建此索引(rowsToDelete
),而不是一次性构建
作为(2)的推论,不要通过迭代连接在一行中创建向量或列表 - 它真的非常慢。
这是一种不同的方式,使用R的矢量化表达式:
rowsToDelete = data$reactionTime > 2000 | data$V8 < 9999
请注意,我已将||
替换为矢量化|
。这将返回一个向量,其元素为TRUE
,满足条件。接下来,我们需要扩展这个逻辑向量,这样,如果索引 i 的元素是TRUE
,则索引 i +1和 i的元素 +2也将是TRUE
:
rowsToDelete = rowsToDelete | c(FALSE, rowsToDelete) | c(FALSE, FALSE, rowsToDelete)
这简单地将向量移动一个元素,然后移动两个元素,并通过逻辑“或”组合它们。但请注意,这会产生警告,因为现在我们通过“或”组合的向量不再具有相同的长度。一般来说,注意这个警告是个好主意。我们可以通过使用一个小辅助函数来避免它:
shift = function (x, element = FALSE) c(element, x[-length(x)])
rowsToDelete = data$reactionTime > 2000 | data$V8 < 9999
rowsToDelete = rowsToDelete | shift(rowsToDelete) | shift(shift(rowsToDelete))