如何使用R中的下一个函数跳过for循环中的迭代[重复]

Posted

技术标签:

【中文标题】如何使用R中的下一个函数跳过for循环中的迭代[重复]【英文标题】:How to skip iterations in a for loop using the next function in R [duplicate] 【发布时间】:2019-09-14 02:54:04 【问题描述】:
 len1 <- sample(1:2,100,replace=TRUE)
df <- data.frame(col1= c(1:200),col2= c(1:200))

for (i in 1:length(len1)) 
  if (len1[i]==1)  
       df$col1[i] <- len1[i] 
  else if (len1[i]==2)  
       df$col1[i] <- len1[i]
       df$col1[i+1] <- 2 
    next
   

每次在 len1 列表中出现“2”时,我想在前一行中添加它并跳过下一次迭代 (i+1)。基本上,每次在 len1 列表中出现“2”时,我都会想要 (i+1)。

所需的最终表格将比 len1 样本长,它应该等于 sum(len1)。 我希望它看起来像这样:每 2 后面跟着一个额外的 2。

> df
   col1 col2
1   2    1
2   2    2
3   1    3
4   2    4
5   2    5
6   1    6 

有什么建议吗?谢谢!

【问题讨论】:

很难理解您的输出,因为您没有将seed 用于len1。我们不知道您的 len1 实际是什么样子以及如何生成所需的输出。 我不明白你所说的种子是什么意思,我认为这是一个可重复的例子。你能更好地描述我的数据集的问题吗? 多次运行sample(1:2,100,replace=TRUE),每次都会得到不同的数字。通过使用set.seed,我们使其可重现。执行set.seed(123)(123 或任何数字)并运行sample(1:2,100,replace=TRUE)。您每次都会得到相同的数字。 我现在明白了,这对我来说并不重要,因为我只想要一个 for 循环,当遇到 len1 文件中的 2 时,它将在 i & i+1 行中放置一个 2。发生这种情况时,我想跳过正在进行的 i 值,以免在复制的 2 行中放置 1 值。 所以如果 len1 是 2 ,将 2 放在 ii + i 行中 col1 或放置 1 ?您还知道 len1 的长度为 100 而 df$col1 的长度为 200 ?我希望您现在也了解提供真实可重复示例的重要性。您有 3 个答案(到目前为止),它们都会根据他们对问题的理解给出不同的答案。 【参考方案1】:

这个问题很难理解。一项重要信息披露in a comment by the OP:

所需的决赛桌将比len1 样本长,它应该 等于sum(len1)

如果我理解正确,如果输入为1,OP 想要将1 复制到输出向量,如果输入向量为@987654327,他想将两个后续2s 复制到输出向量@。

如果我的理解是正确的,那么就是这样

rep(len1, times = len1)

会。

所以,有一个适当的可重现的例子

n_row <- 10L
set.seed(2L)
len1 <- sample(1:2, n_row , replace = TRUE)
len1
[1] 1 2 2 1 2 2 1 2 1 2
rep(len1, times = len1)

返回

[1] 1 2 2 2 2 1 2 2 2 2 1 2 2 1 2 2

当然,sum(len1) == length(rep(len1, times = len1))TRUE

因此,data.frame 可以由

创建
data.frame(col1 = rep(len1, times = len1), col2 = seq_len(sum(len1)))

修复for 循环(不推荐)

如果我对 OP 意图的理解是正确的,可以通过为输出向量引入单独的计数 j 来修复 OP 的 for 循环:

df <- data.frame(col1 = seq_len(sum(len1)), col2 = seq_len(sum(len1)))
j <- 1L
for (i in 1:length(len1)) 
  if (len1[i] == 1L) 
    df$col1[j] <- len1[i]
    j <- j + 1L
  
  else if (len1[i] == 2L) 
    df$col1[j] <- len1[i]
    df$col1[j + 1L] <- 2L
    j <- j + 2L
  

df
   col1 col2
1     1    1
2     2    2
3     2    3
4     2    4
5     2    5
6     1    6
7     2    7
8     2    8
9     2    9
10    2   10
11    1   11
12    2   12
13    2   13
14    1   14
15    2   15
16    2   16

【讨论】:

谢谢 Uwe,我显然需要学习如何更好地制作可重现的样品。这很有帮助,因为我是 R 新手,而且很多功能对我来说都是陌生的。【参考方案2】:

使用skip 变量,该变量在设置时始终重置为FALSE

skip <- FALSE
for (i in 1:length(len1)) 
  if (skip) 
    skip <- FALSE
    next
  
  if (len1[i]==1)  
    df$col1[i] <- len1[i]
   else if (len1[i]==2)  
    df$col1[i] <- len1[i]
    df$col1[i+1] <- 2 
    skip <- TRUE
   

【讨论】:

这很好,但它正在做一些不可取的事情。它跳过了 len1 列表中前面的 1。你看到问题了吗? 所需的最终表将比 len1 样本长,它应该等于 sum(len1)【参考方案3】:

换一种说法,如果之前的len1 为2,您希望col1 为2,否则len1

我们可以使用c(1, len1[-length(len1)]) 创建一个滞后向量,以确定一行是否应将前一个len12 作为其值。 1 被添加到开头,因为第一行应该采用 len1 的值。

如果ifelse:

df$col1 <- ifelse(
    c(1, len1[-length(len1)]) == 2,
    2, # if prev is 2, value is 2
    len1 #value of len1 otherwise
)

正如评论中所指出的,由于涉及sample函数,它每次都会给出不同的结果,所以这里没有必要展示结果。

【讨论】:

【参考方案4】:

好吧,我想你想要的是

while (i <= length(len1)) 
  if (len1[i]==1)  
       df$col1[i] <- len1[i] 
  else if (len1[i]==2)  
       df$col1[i] <- len1[i]
       df$col1[i+1] <- 2 
       i = i + 1
   
  i = i + 1

在您的问题中,您声明您希望跳过 next 循环,但使用 next 会跳出 current 迭代并进入下一个迭代。使用while 循环可以让您更好地控制增量,在这种情况下,我们根据len1[I] 的值将12 添加到计数器,这意味着我们基本上可以向前跳过。

【讨论】:

以上是关于如何使用R中的下一个函数跳过for循环中的迭代[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何有条件地跳过python中for循环中的迭代步骤数?

如何跳过“foreach”循环的迭代?

转到基于范围的 for 循环中的下一个迭代器

VBA - 如何有条件地跳过for循环迭代

如果满足条件,则移动到嵌套 for 循环中的下一次迭代

Python:如果条件为真,则跳过 For 循环中的迭代