how to restart a for loop if condition is met

45 Views Asked by At

I have a dataframe of percentages and am trying to adjust it so that all percents in each column are at least 2 percentage points different from all other percents in that column so that they will be displayed nicely on a chart.

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

Currently I'm using a for-loop, which works except that it is one-directional:

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
  }
 }
}

In this situation, when r=1 and c=2, the if condition wouldn't be met, because 29-26>2, then r=2 and c=2, the if condition would be met and 26 would become 28. However, that puts it too close to 29, so I want to go back to r=1 and recheck, so that 29 can be moved up to 31. Is there a way to restart a for-loop in r if a specific condition is met?

Expected output:

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

There are 1 best solutions below

0
r2evans On

I'm not sure this is the best way, but assuming you are needing to more than "just" plot things ...

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)
  }
}

Another way that uses R's lapply fairly fluidly is:

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

Data

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))