【问题标题】:For and If in R data programmingR 数据编程中的 For 和 If
【发布时间】:2026-01-22 20:05:01
【问题描述】:

我想评估非零数据之间的距离。所以如果我有 50 个数据,并且只有第一个和最后一个数据是非零的,那么我希望结果是 49。

比如我的数据是:

1. 0
2. 0
3. 5
4. 6
5. 0
6. 1
7. 0

根据我上面的数据,我想得到 4 个变量:

v0 = 3 (because the distance between 0th to 3rd data is 3 jumps)
v1 = 1 (because the distance between 3rd to 4th data is 1 jump)
v2 = 2 (because the distance between 4rd to 6th data is 2 jump)
v3 = 1 (because the distance between 6rd to 7th data is 1 jump)

这是我的代码:

data=c(0,0,5,6,0,1,0)

t=1
for (i in data) {
  if (i == 0) {
    t[i]=t+1
  }
  else {
    t[i]=1
  }
}

t

结果是:

[1]  1 NA NA NA  1  1

您能帮我解决这个问题吗?我也希望代码使用某种循环,以便它可以应用于任何其他数据。

【问题讨论】:

  • 我不明白为什么 v0 从第 0 跳到第 3?
  • 在您的代码中,您使用 i 来设置 t[i] 的值。但我假设您的矢量数据中的所有值(而不是从 1 到矢量数据长度的值。所以这仅表示值 t[0]、t[1]、t[5] 和 t[6]将被分配一个值,其余的将是未定义的(NA)。所以你的代码按预期工作。我不确定你到底想得到什么作为输出,所以我无能为力。

标签: r loops for-loop if-statement


【解决方案1】:

问题中的一般规则尚不清楚,但如果x 是我们假设的输入:

  • 输入为非负数
  • 输出中的第一个元素是x 中第一个+ve 元素的位置
  • 输出的后续元素是x的连续+ve元素之间的距离
  • 如果这导致向量的和小于length(x),则追加余数

要确定c(1, x) 的正元素的位置,请使用diff 计算该缩减向量中的连续元素之间的差异,然后如果它们的总和不等于length(x),则追加余数。

dists <- function(x) {
  d <- diff(which(c(1, x) > 0))
  if (sum(d) < length(x)) c(d, length(x) - sum(d)) else d
}

# distance to 5 is 3 and then to 6 is 1 and then to 1 is 2 and 1 is left
x1 <- c(0, 0, 5, 6, 0, 1, 0)
dists(x1)
## [1] 3 1 2 1

# distance to first 1 is 1 and from that to second 1 is 3
x2 <- c(1, 0, 0, 1)
dists(x2)
## [1] 1 3

这里使用循环重做:

dists2 <- function(x) {
  pos <- 0
  out <- numeric(0)
  for(i in seq_along(x)) {
    if (x[i]) {
      out <- c(out, i - pos)
      pos <- i
    }
  }
  if (sum(out) < length(x)) out <- c(out, length(x) - sum(out))
  out
}

dists2(x1)
## [1] 3 1 2 1

dists2(x2)
## [1] 1 3

更新

基于以下答案的 cmets 进行简化。添加了循环方法。

【讨论】:

  • 和任何答案一样好。小问题:在某些情况下,“非零”可能“小于零”。此外,您的d 可以更简单地定义为diff(which(c(1,x) != 0))
  • 基于输入为非负的问题中的示例。使用which添加了您的简化。