Как пропустить итерацию для цикла, если условие выполнено - PullRequest
1 голос
/ 25 сентября 2019

У меня есть код, чтобы превратить верхний треугольник матрицы в вектор и сохранить значения этого вектора вместе с их исходными координатами из матрицы в кадре данных.Как пропустить цикл for, если элемент в векторе равен нулю?

Я пробовал операторы else и другие попытки.

v <- matrix(sample(0:1, 10, replace = TRUE),9,9)
t <- v[upper.tri(v,diag=T)]
tful <- t[t!=0]
df <- data.frame(FP1=rep(0,length(t)),FP2=rep(0,length(t)),tanimoto=rep(0,length(t)))
for (i in 1:length(t)){
  if (t[i]==0) next
  else {
      col_num <- floor(sqrt(2*i-7/4)+.5)
      row_num <- i-(.5*col_num^2-.5*col_num+1)+1
      df$FP1[i] <- row_num
      df$FP2[i] <- col_num
      df$tanimoto[i] <- v[row_num,col_num]
    }
}

Я не хочу, чтобы в моем фрейме данных были нули,и цикл, чтобы пропустить эти значения.Я понимаю, что фрейм данных должен быть меньше в строках, но я использую это в качестве примера.

1 Ответ

1 голос
/ 25 сентября 2019

Ваш next работает нормально, чтобы пропустить текущую итерацию цикла.

В конечном результате вы все равно получаете 0 с, поскольку все значения df были инициализированы df равным 0. Когда вы пропускаетеитерации, они не изменяются, поэтому они остаются равными 0. Если вы измените инициализацию на значения NA, вы увидите, что нулевые значения не добавляются.

df <- data.frame(FP1=rep(NA,length(t)),FP2=rep(NA,length(t)),tanimoto=rep(NA,length(t)))
for (i in 1:length(t)){
  if (t[i]==0) next
  else {
      col_num <- floor(sqrt(2*i-7/4)+.5)
      row_num <- i-(.5*col_num^2-.5*col_num+1)+1
      df$FP1[i] <- row_num
      df$FP2[i] <- col_num
      df$tanimoto[i] <- v[row_num,col_num]
    }
}
df
#    FP1 FP2 tanimoto
# 1    1   1        1
# 2    1   2        1
# 3    2   2        1
# 4    1   3        1
# 5    2   3        1
# 6    3   3        1
# 7   NA  NA       NA
# 8    2   4        1
# 9    3   4        1
# 10   4   4        1
# 11  NA  NA       NA
# ...

Простая модификация - фильтровать ваши данные.последний кадр: df = df[df$tanimoto != 0, ], или если вы переключитесь на NA, df = na.omit(df).

Мы также могли бы создать решение без зацикливания:

v1 = v != 0 
df2 = data.frame(FP1 = row(v)[v1], FP2 = col(v)[v1], tanimoto = v[v1])
df2 = subset(df2, FP1 <= FP2)
df2
#    FP1 FP2 tanimoto
# 1    1   1        1
# 7    1   2        1
# 8    2   2        1
# 13   1   3        1
# 14   2   3        1
# 15   3   3        1
# 20   2   4        1
# 21   3   4        1
# 22   4   4        1
# 27   3   5        1
# 28   4   5        1
# 29   5   5        1
# 33   1   6        1
# 34   4   6        1
# 35   5   6        1
# ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...