Функция R для сравнения двух векторов. Работает в Repex, но не применительно к моим данным - PullRequest
0 голосов
/ 25 июня 2019

Что я хочу сделать:

У меня есть два вектора.Первый содержит минимальную температуру, а второй содержит максимальную температуру.Функция, которую я написал, должна сравнивать их, строка за строкой, и для каждой строки возвращать функцию с большим абсолютным значением (без фактического применения к ней abs ()).Но: если их абсолютные значения равны (например, max = 5, min = -5), он должен вернуть NA.Если они оба равны 0, он должен вернуть 0.

Проблема:

Моя проблема заключается в том, что он никогда не возвращает 0, даже если должен.Вместо этого он возвращает NA.Когда я пытался сделать репекс, я не мог воссоздать проблему.Это работает на маленьких векторах, которые я создал.Он даже отлично работает на подмножествах моих данных, но когда я применяю его к полному набору данных, это не так.

То, что я пробовал:

Я добавил несколько операторов печати всама функция и цикл for, который применяет функцию к моим данным, чтобы найти случаи, в которых должен быть возвращен 0.Применительно к полному набору он дает мне NA, где должно быть 0. Когда я создал подмножество данных, в которых это происходит, функция неожиданно сработала.Когда я изобрел некоторые данные для проверки функции, она также работала.Я попытался перезапустить Rstudio, удалив рабочее пространство, включая скрытые объекты.Проблема остается.

Функция:

# invent some data:
mins_ <- c(0,0,-4,-5,7,10)
maxs_ <- c(0,-1,4,-5,12,-5)


# my function:
# I edited my function according to docendo discimus' answer (thanks!)
# it's more readable now, but the problem is still there.
# Here's the updated function:

getmaxmin <- function(vmax,vmin){
  # create vector to store the results
  dTmp10_minmax <- numeric(length = length(vmax))
  for (i in 1:length(dTmp10_minmax)) {
    # if both are zero, store zero
    if ((vmax[i] == 0) == T & (vmin[i] == 0) == T){
      # print statement to find the cases where this is supposed to happen:
      print(i)
      dTmp10_minmax[i] <- 0
    } else {
      # if both are equal but not zero, store NA in vector
      if (vmin[i] != 0 & vmax[i] != 0 & abs(vmax[i]) == abs(vmin[i]) ) {
        dTmp10_minmax[i] <- NA
      } else {
        if (abs(vmax[i]) < abs(vmin[i])) {
          dTmp10_minmax[i] <- vmin[i]
        } else {
          if (abs(vmax[i]) > abs(vmin[i])) {
            dTmp10_minmax[i] <- vmax[i]
          }
        }
      }
    }
  }
  return(dTmp10_minmax)
}

# apply to data
test <- getmaxmin(vmin = mins_, vmax = maxs_)

# result:
> test
[1]  0 -1 NA NA 12 10

# as you can see, this works fine, but when I try applying it to my list of 
# datasets, it returns NA where there should be 0
# I apply it like this:

for (i in 1:length(file_list)){
  d_Temp_p3_10minmax <- getmaxmin(vmax = datas[[i]]$d_Temp_p3_10max, vmin = datas[[i]]$d_Temp_p3_10min)
  print(paste("data",i))
  datas[[i]] <- cbind(datas[[i]], d_Temp_p3_10minmax)
}

# datas is a list of 45 large datasets, file_list is a character vector
# containing the names of these sets

Нет ни предупреждений, ни сообщений об ошибках.Функция работает с частями данных, но не при использовании через цикл for.

1 Ответ

1 голос
/ 25 июня 2019

Я предлагаю значительно упростить вашу функцию, что упростит отладку и выполнение функции более эффективно, так как вы будете использовать векторизованные функции, как было разработано R.

foo = function(x, y) {
  res = pmax(abs(x), abs(y))
  res[abs(x) == abs(y)] = NA
  res[x == 0 & y == 0] = 0
  res
}

foo(mins_, maxs_)
# [1]  0  1 NA NA 12 10

Редактировать:

Если вы хотите сохранить знаки, вы можете настроить вышеуказанную функцию следующим образом:

foo = function(x, y) {
  res = pmax(abs(x), abs(y))
  res[abs(x) == abs(y)] = NA
  res[x == 0 & y == 0] = 0
  idx_not_abs_x = res != abs(x) & !is.na(res) & res != 0
  res[idx_not_abs_x] = res[idx_not_abs_x] * sign(y[idx_not_abs_x])
  res[!idx_not_abs_x] = res[!idx_not_abs_x] * sign(x[!idx_not_abs_x])
  res
}

foo(mins_, maxs_)
#[1]  0 -1 NA NA 12 10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...