Как включить логические проверки в пользовательскую функцию - PullRequest
0 голосов
/ 09 января 2019

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

Прямо сейчас у меня есть функция, написанная с помощью серии операторов if / else. Однако это предупреждение о том, что он использует только первый элемент строки операторов T / F. Упрощенный пример моей функции следующий:

myfun = function(temp,data) {
    if(temp > 34){
    warning('Temperature higher than expected')
  }
    if (data > 50) {
      result = temp*data
      return(result)
    } else if(data <= 50) {
      result = temp/data
      return(result)
    }
  }

myfun(temp = c(25,45,23,19,10), data = c(30,40,NA,50,10))

Как видите, поскольку он использует только первое значение для операторов if / else, он не вычисляет должным образом возвращаемые значения, поскольку не переключается между двумя версиями преобразования. Кроме того, он только проверяет, находится ли первое значение температуры выше порога. Как я могу заставить его правильно применять логическую проверку к каждому значению, а не только к первому?

-edit-упростил функцию согласно предложению @ The_Questioner и изменил <50 на <= 50. </p>

1 Ответ

0 голосов
/ 09 января 2019

Основная проблема с вашим кодом заключается в том, что вы передаете все значения функциям как векторы, но затем выполняете сравнения отдельных элементов. Вам нужно либо передать элементы один за другим в функцию, либо поместить какое-либо векторизованное сравнение или цикл for в вашу функцию. Ниже описан подход for loop , который, вероятно, является наименее элегантным способом сделать это, но, по крайней мере, легко понять, что происходит.

Другая проблема заключается в том, что NA, по-видимому, необходимо обработать в векторе data , прежде чем переходить к любому из ваших условных операторов, иначе вы получите ошибку.

Последний вопрос - что делать, когда data = 50. Сейчас у вас есть условные тесты для значений больше или меньше 50, но, как вы можете видеть, 4-й пункт в data 50, так что сейчас вы получаете АН.

myfun = function(temp,data) {
    result <- rep(NA,length(temp))
    for (t in 1:length(temp)) {
        if(temp[t] > 34) {
            warning('Temperature higher than expected')
            if (!is.na(data[t])) {
                if (data [t] > 50) {
                    result[t] <- temp[t]*data[t]
                } else if(data[t] < 50) {
                    result[t] <- temp[t]/data[t]

                }
            }
        } else {
            if (!is.na(data[t])) {
                if (data[t] > 50) {
                    result[t] <- temp[t]*data[t]

                } else if(data[t] < 50) {
                    result[t] <- temp[t]/data[t]

                }
            }
        }
    }
    return(result)
}

Выход:

> myfun(temp = c(25,45,23,19,10), data = c(30,40,NA,50,10))
[1] 0.8333333 1.1250000        NA        NA 1.0000000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...