вычисление минимумов фрагментов вектора: пропущенное значение, где требуется ИСТИНА / ЛОЖЬ - PullRequest
0 голосов
/ 06 января 2020

Я хочу собрать все минимальные ненулевые значения пробегов вектора, разделенных нулями. Таким образом, результаты применения моего кода к вектору x ниже должны быть -1, -9: -1 из -1, 5 и -9 из -4, -9.

Я запускаю приведенный ниже код и получаю следующее сообщение:

Ошибка в if ((temp [i] == 0) && (temp [i + 1]! = 0)) {: пропущенное значение, где требуется TRUE / FALSE

x <- c(0, 0, -1, 5, 0, 0, -4, -9, 0)
temp = c()
minV = c()
for (i in 1:length(x)-1){
    temp[i] <- x[i]
    if((temp[i] == 0) && (temp[i+1] != 0)){
        minV <- c(minV,min(temp))
        temp <- c()
    }
}
minV

Что я могу сделать, чтобы достичь своей цели?

Ответы [ 3 ]

4 голосов
/ 06 января 2020

Оператор : имеет более низкий приоритет, чем -. Это означает, что 1:n - 1 совпадает с seq(0,n-1), а не seq(1,n-1).

3 голосов
/ 06 января 2020

Итак, в коде есть несколько проблем:

  1. Вы пытаетесь оценить temp [i + 1], когда он еще не создан, но это приведет к NA.
  2. Поскольку вы индексируете, используя i, после того как вы освободите temp в середине l oop, когда он встретит ноль, он не добавит значение к началу temp, вместо этого он добавит в середину.
  3. При зацикливании вы зацикливаетесь на 1:length(x)-1, что приводит к 0-8, вместо этого вы хотите сделать это 1:(length(x) - 1)

Вот исправление кода;

# Creating data
x <- c(0, 0, -1, 5, 0, 0, -4, -9, 0)

# Create temp place holders
temp = c()
minV = c()

# Loop on x vector
for (i in 1:(length(x)-1)){
  # If x[i] is not zero
  if(x[i] != 0){
    # Append to temp
    temp <- c(temp, x[i])

    # If next value is zero then get minimum
    if(x[i+1] == 0){
      # Get minimum
      minV <- c(minV, min(temp))
      # Free temp
      temp <- c()
    }
  }
}
minV
# -1 -9

Однако лучший способ - вырезать вектор всякий раз, когда он встречает ноль, а затем получать минимум каждого из разбиений следующим образом:

# Creating data
x <- c(0, 0, -1, 5, 0, 0, -4, -9, 0)

# Split string at occurances of zeros
ll <- with(rle(x == 0),{
  ifelse(x == 0 & (seq_along(x) != cumsum(lengths)[lengths <= 3 & values]), NA, x)
})
x_split <- split(x, with(rle(is.na(ll)), rep(1:length(lengths), lengths) + ll * 0))

# Get minimum of each vector as list of minimum(s)
lapply(x_split, min)
# $`2`
# [1] -1
# 
# $`4`
# [1] -9

# Or get it in form of vector
unlist(lapply(x_split, min), use.names = FALSE)
# [1] -1 -9

# Or use sapply automatically [credit to Ben Bolker]
sapply(x_split, min)
# [1] -1 -9
1 голос
/ 06 января 2020

Вот еще одна альтернатива, если это поможет?

x <- c(0, 0, -1, 5, 0, 0, -4, -9, 0)

accumulated.values <- NULL
min.values <- NULL

for (value in x) {

  # if we hit a 0
  if (value == 0) {

    # and we have some values accumulated 
    if (!is.null(accumulated.values)) {

      # calculate the minimum value of the accumulated values
      min.values <- c(min.values, min(accumulated.values))

      # clear the accumulated values 
      accumulated.values <- NULL
    }

    # otherwise ignore
  }
  else {

    # add the value to the accumulated list
    accumulated.values <- c(accumulated.values, value)
  }
}

min.values
# [1] -1 -9
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...