如果满足条件,如何跳过for循环中的迭代
How to skip iteration in for loop if condition is met
我有代码可以将矩阵的上三角转换为向量,并将该向量的值连同它们在矩阵中的原始坐标一起存储到数据框中。
如果向量中的元素为零,如何跳过 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]
}
}
我不希望我的数据框中有任何零,并且循环跳过这些值。
我知道数据框的行数需要更小,但我以此为例。
您的 next
可以正常跳过循环的当前迭代。
你在最终结果中仍然得到 0,因为 df
的所有值都被 df 初始化为 0。当你跳过迭代时,它们没有改变,所以它们仍然是 0。如果你将初始化更改为是 NA 值,你会看到没有添加 0。
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
# ...
我有代码可以将矩阵的上三角转换为向量,并将该向量的值连同它们在矩阵中的原始坐标一起存储到数据框中。 如果向量中的元素为零,如何跳过 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]
}
}
我不希望我的数据框中有任何零,并且循环跳过这些值。 我知道数据框的行数需要更小,但我以此为例。
您的 next
可以正常跳过循环的当前迭代。
你在最终结果中仍然得到 0,因为 df
的所有值都被 df 初始化为 0。当你跳过迭代时,它们没有改变,所以它们仍然是 0。如果你将初始化更改为是 NA 值,你会看到没有添加 0。
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
# ...