如果满足条件,如何重新启动 FOR 循环

how to restart a for loop if condition is met

提问人:Emily 提问时间:11/8/2023 最后编辑:r2evansEmily 更新时间:11/8/2023 访问量:39

问:

我有一个百分比数据框,并正在尝试对其进行调整,以便每列中的所有百分比与该列中的所有其他百分比至少相差 2 个百分点,以便它们在图表上很好地显示。

df <- data.frame(c("group1", "group2", "group3", "group4"),c(29, 26, 25, 12),c(8, 7, 3, 2))
names(df) <- c("group","var1","var2")

目前我正在使用 for 循环,它有效,但它是单向的:

for(c in 2:ncol(df){
 for(r in 1:nrow(df)){
  if(df[r,c]-order_df[r+1,c]<2){
    group <- df$group[r]
    df[[c]][df$group==group] <- df[[c]][df$group==group]+2
  }
 }
}

在这种情况下,当 are=1 和 c=2 时,将不满足 if 条件,因为 29-26>2,然后 r=2 和 c=2,将满足 if 条件,26 将变为 28。但是,这太接近 29,所以我想回到 r=1 并重新检查,以便 29 可以向上移动到 31。如果满足特定条件,有没有办法在 r 中重新启动 for 循环?

预期输出:

expected <- data.frame(group=c("group1", "group2", "group3", "group4"),var1=c(31, 28, 25, 12),var2=c(10, 7, 5, 2))
r for 循环 if 语句 重新启动

评论

3赞 r2evans 11/8/2023
我不认为双循环一定是解决这个问题的最佳方式,但无论哪种方式......给定此输入,(或“一个”)预期输出是多少?for
3赞 I_O 11/8/2023
请注意,您可以避免将点与基 R 的函数和 的参数重叠(不弄乱原始数据)。jitterggplotjittergeom_point
0赞 Carl Witthoft 11/8/2023
正如I_O所说,这是解决这个问题的错误方法。但在一般情况下,应避免设置条件,其输出将更改以前的条件。存在无限循环的真正风险。
0赞 r2evans 11/8/2023
除了I_O的/建议之外,如果您唯一关心的是绘图期间并且您已经在使用 ,请考虑一下,它会非常努力地防止标签重叠。jittergeom_pointggplot2ggrepel::geom_text_repel
1赞 Friede 11/8/2023
它是什么样子的?order_df

答:

1赞 r2evans 11/8/2023 #1

我不确定这是最好的方法,但假设你需要的不仅仅是“只是”策划事情......

for (col in 2:3) {
  for (i in rev(seq_len(nrow(df)-1))) {
    df[[col]][i] <- df[[col]][i] + 2*sum(abs(df[[col]][i] - df[[col]][-(1:i)]) < 2)
  }
}

另一种相当流畅地使用 R 的方法是:lapply

df
#    group var1 var2
# 1 group1   29    8
# 2 group2   26    7
# 3 group3   25    3
# 4 group4   12    2
df[,2:3] <- lapply(df[,2:3], function(z) {
  for (i in rev(seq_along(z))[-1]) {
    z[i] <- z[i] + 2*sum(abs(z[i] - z[-(1:i)]) < 2)
  }
  z
})
df
#    group var1 var2
# 1 group1   31   10
# 2 group2   28    7
# 3 group3   25    5
# 4 group4   12    2

数据

df <- data.frame(group=c("group1", "group2", "group3", "group4"),var1=c(29, 26, 25, 12),var2=c(8, 7, 3, 2))
expected <- data.frame(group=c("group1", "group2", "group3", "group4"),var1=c(31, 28, 25, 12),var2=c(10, 7, 5, 2))