Оператор R if неправильно передается при использовании функции в tibble

#r #data-wrangling

#r #перебор данных

Вопрос:

Я запутался в этом в течение последнего часа, и может кто-нибудь мне помочь.

Вот мой код, в котором я пытаюсь создать 2 функции, которые будут использоваться в tibble() . введите описание изображения здесь

 n <- 1000
w <- function(x) {
  if(-2 <= x amp; x <= 2) {
    return((-3/32)*x^2   3/8)
  }else{
    return(0)
  }
}
y <- function(x){
  if(0 <= x amp; x <= 8){
    return((1/8)*x^(-2/3) - (1/32))
  }else{
    return(0)
  }
}
df <- tibble(value = seq(2, 9, length.out = n), W = w(value), Y = y(value))
head(df)
 

Как вы видите, W возвращает отрицательное значение, когда значения больше 2, но в моей функции w() есть оператор if, чтобы ограничить это.

Итак, что происходит и как мне решить эту проблему?

Комментарии:

1. Только первый элемент в вашей последовательности удовлетворяет обоим логическим условиям, поэтому вы получаете ровно один 0 от w функции. Я покажу вам, как исправить исходную синтаксическую ошибку ниже, но я предполагаю, что проблема скорее семантическая проблема в вашей голове.

2. почему отрицательное значение in w является проблемой? Вы сказали, что хотите иметь значение w между -2 и 2. Эти значения w находятся в этом диапазоне.

3. НЕ используйте return этот способ.

Ответ №1:

Вы использовали if / else , который работает для одного ввода (скалярный), и вы передаете ему несколько значений (вектор). Вы должны использовать ifelse который векторизован.

Если я правильно вас понял w , вы хотите применить формулу (-3/32)*x^2 3/8 , но если значение отрицательное, присвоите значение 0. То же самое для y того, где вы хотите применить формулу (1/8)*x^(-2/3) - (1/32) . Вы можете изменить свою функцию на.

 w <- function(x) {
  pmax((-3/32)*x^2   3/8, 0)
}

y <- function(x){
  pmax((1/8)*x^(-2/3) - (1/32), 0)
}

df <- tibble(value = seq(2, 9, length.out = n), W = w(value), Y = y(value))
head(df)
 

pmax выбирает максимум из обоих переданных входных данных. Например,

 pmax(-5:5, 0)
#[1] 0 0 0 0 0 0 1 2 3 4 5
 

Комментарии:

1. Эй, чувак, я распознал проблему в использовании if / else и, наконец, использовал ifelse() , но я хочу выдавать значения от -2 до 2, а не только положительные значения, для которых, как я предполагаю, используется pmax(), я использовал between(n, -2, 2) тем не менее, он все еще не выдал 0, когда его внешние значения -2 и 2.

2. Итак w , вы хотите применить формулу (-3/32)*x^2 3/8 и сохранить только значения между -2 и 2, а остальные из них превратить в 0?

3. да, я просмотрел документацию between() и поскольку мой вектор последовательности не имеет значения -2 или 2, для которого я предполагаю, что он округляется. Но все же, при просмотре моего фрейма данных, все еще существуют значения для входных данных, которые находятся за пределами -2 и 2

4. @AntonyD : Озадачен. Ваш первый элемент в df$value равен 2. А (-3/32)*2^2 3/8 также равен 0. Так что в этом случае решения ifelse действительно спорны. Не уверен, какая часть вашего фрейма данных вас беспокоит. Пожалуйста, будьте более конкретны в своем изложении проблемы.

Ответ №2:

Вот код, который выполняет то, что вы хотите, для гораздо меньшего тестового примера, который по-прежнему позволяет просматривать все диапазоны ваших значений (я взял на себя смелость расширить диапазон тестирования значений, потому что в исходном случае, когда x было от -2 до 2, был только один экземпляр, и это дало 0для w(2) независимо.

 n <- 10
w <- function(x) {
    ifelse( -2 <= x amp; x <= 3 , (-3/32)*x^2   3/8, 0) 
                 }
y <- function(x){
    ifelse (0 <= x amp; x <= 8, (1/8)*x^(-2/3) - (1/32), 0)
                  }
df <- tibble(value = seq(2, 9, length.out = n), W = w(value), Y = y(value))
#-----------

df
# A tibble: 10 x 3
   value      W       Y
   <dbl>  <dbl>   <dbl>
 1  2     0     0.0475 
 2  2.78 -0.348 0.0320 
 3  3.56  0     0.0224 
 4  4.33  0     0.0158 
 5  5.11  0     0.0109 
 6  5.89  0     0.00708
 7  6.67  0     0.00404
 8  7.44  0     0.00154
 9  8.22  0     0      
10  9     0     0      
 

Более ранние наблюдения:
Ваш код выдал ошибку, и я исправил ее, внеся пару незначительных изменений в w функцию:

 w <- function(x) {
    if( (-2 <= x) amp;amp; (x <= 2)) {
        (-3/32)*x^2   3/8)
    } else { 0   }
}
 

Я думаю, что использование ‘return’ могло вызывать проблемы.

Выражение в вашей первой версии выдало эту ошибку:

 Error: unexpected '<=' in:
"w <- function(x) {
    if(-2 <= x <="
 

… потому что математически разумное -2 <= x <= 2 просто не подходит для синтаксического анализа в R.

Комментарии:

1. Я использовал ifelse(между (x, -2, 2), return((-3 / 32) * x ^ 2 3/8), return(0)), и ti действительно работал, но по какой-то причине он все равно выдавал значения за пределами 2 и -2, когда он должен был не выполнять условиеи просто возвращает 0

2. Я сомневаюсь, что было бы правильно использовать ‘return’ во втором или третьем аргументах для ‘ifelse’