R: Функция() — Как проверить значения x y с помощью if else и sapply

#r #function #if-statement

Вопрос:

Это всего лишь пример того, что я хочу сделать.. я пытаюсь проверить, больше ли «Numbers2», чем «Numbers» .. с помощью кода ниже.. я делаю это неправильно? это небольшая проблема, но я новичок в R.. Я не получаю желаемый результат, и я не могу найти проблему. вывод с текущим кодом

 df = data.frame(YesNo = c("yes","no","yes","no"), 
            Numbers = c(4, 5, 10, 10),
            Numbers2 = c(5,1,11,11))
df

rownames(df) = c("Test1","Test2","Test3","Test4")
df


improvement1 = function(x,y) {
  if(x >= y){
    return("Improve")
  } else {
    return("No")
  }
}

df$Improvement=sapply(df$Numbers, df$Numbers2, FUN=improvement1)
View(df)
 

Ответ №1:

Эта проблема связана с if , которая ожидает одно логическое значение. Однако вы сравниваете два вектора. Мы получаем это предупреждение в вашем коде:

 Warning messages:
1: In if (x >= y) { :
  the condition has length > 1 and only the first element will be used
 

Поскольку используется только первый элемент, вы получаете неожиданные результаты. Вам нужно векторизованное решение, которое таково ifelse() .

 improvement1 = function(x,y) {
  ifelse(x >= y, "Improve", "No")
}

df$Improvement = improvement1(df$Numbers, df$Numbers2)
df
      YesNo Numbers Numbers2 Improvement
Test1   yes       4        5          No
Test2    no       5        1     Improve
Test3   yes      10       11          No
Test4    no      10       11          No
 

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

1. Также обратите внимание, что sapply() здесь есть проблема. Так как вы подаете в двух векторах, sapply() будет возвращена матрица 2×2.

2. даже с ifelse он все равно показывает неправильный вывод, верно? в вашем коде выше.. он не показывает правильный вывод для Test1 и Test2

Ответ №2:

> компаратор векторизован, вам вообще не нужны циклы.

 df$Improvement<-c('NO', 'Improve')[1   (df$Numbers > df$Numbers2)]

#Or just use ifelse as in @Ben Norris' answer:

df$Improvement=ifelse(Numbers>Numers2, 'Improvement', 'No')
 

Если вы действительно хотите использовать функцию цикла, вы должны использовать mapply() , как в:

 df$Improvement=mapply(FUN=improvement1, df$Numbers, df$Numbers2)
 

mapply циклы через несколько векторных вменений по элементам.
Когда мы вызываем mapply(my_function, x, y) , на выходе c(my_function(x[[1]], y[[1]]), my_function(x[[2]], y[[2]]), .....) получается то, что вам нужно