Несколько присваиваний переменных в ifelse () - PullRequest
0 голосов
/ 20 сентября 2018

Какую ошибку я здесь делаю?Я пытаюсь присвоить a и b какое-либо значение, если любое из трех утверждений верно.Я пытаюсь использовать оператор ifelse:

ifelse(1==1||2==2||3==3, (a<-100,b<-100), (a<-1000,b<-1000)) 

Но я получаю сообщение об ошибке:

Ошибка: неожиданно ',' in "ifelse (1 == 1 || 2 == 2 || 3 == 3, (a <-100, "</p>

Отредактировано:

В более обобщенном виде, есть две переменные a и b, которыенеобходимо назначить разные значения в зависимости от условий: если (x == "кошка" или x == "собака" или x == "лошадь", то a равно 100 и b равно 200, иначе a равно 500 и b1000)

Ответы [ 3 ]

0 голосов
/ 20 сентября 2018

Вы можете думать о ifelse() в R как о функции, которая работает с 3 векторами:

  1. вектор логических значений (ИСТИНА, ЛОЖЬ).Это 1==3 | 2==2 | 3==3 part.
  2. вектор элементов, который будет выбран, когда первый вектор равен TRUE.Это a <- 100 part.
  3. вектор элементов, который будет выбран, когда первый вектор равен FALSE.Это a <- 1000 часть.

И все 3 вектора должны иметь одинаковую длину.

Вот краткая демонстрация:

vec1 <- 1:10 > 3 & 1:10 < 7
> vec1
 [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE

vec2 <- LETTERS[1:10]
> vec2
 [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J"

vec3 <- letters[1:10]
> vec3
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"

Функция ifelse() объединит vec2 и vec3 в новый вектор, в котором элементы взяты из vec2 и vec3 в зависимости от значения vec1.

ifelse(vec1, vec2, vec3)
 [1] "a" "b" "c" "D" "E" "F" "g" "h" "i" "j"

Toлучше посмотреть, как это работает, здесь все в табличной форме (предложено @Gregor).

> rbind(vec1, vec2, vec3, result=ifelse(vec1, vec2, vec3))
       [,1]    [,2]    [,3]    [,4]   [,5]   [,6]   [,7]    [,8]    [,9]    [,10]
vec1   "FALSE" "FALSE" "FALSE" "TRUE" "TRUE" "TRUE" "FALSE" "FALSE" "FALSE" "FALSE"
vec2   "A"     "B"     "C"     "D"    "E"    "F"    "G"     "H"     "I"     "J"
vec3   "a"     "b"     "c"     "d"    "e"    "f"    "g"     "h"     "i"     "j"
result "a"     "b"     "c"     "D"    "E"    "F"    "g"     "h"     "i"     "j"

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

В вашем случае решение, все еще использующее ifelse(), будет состоять в том, чтобы сделать это два раза:

a <- ifelse(x=="cat" | x=="dog" | x=="horse", 100, 500)
b <- ifelse(x=="cat" | x=="dog" | x=="horse", 200, 1000)

ПРИМЕЧАНИЕ: в приведенном выше примере вместо вектора было указано одно значение 100.Но R расширит свою длину, чтобы соответствовать длине первого вектора.Поэтому допустимы отдельные значения, но они расширяются до вектора под капотом.

0 голосов
/ 20 сентября 2018

Отвечая на вопрос, красиво сформулированный ОП в комментариях:

если (x == "кошка" или x == "собака" или x == "лошадь", то a100 и b равно 200, иначе a равно 500 и b равно 1000)

if (x == "cat" || x == "dog" || x == "horse") {
  a = 100
  b = 200 
} else {
  a = 500
  b = 1000
}

Мы можем добиться большего успеха, используя %in% вместо | - работает хорошо, особенно если у вас естьЕще больше значений для проверки

if (x %in% c("cat", "dog", "horse")) {
  a = 100
  b = 200 
} else {
  a = 500
  b = 1000
}

ifelse - это векторизованная функция, которая возвращает вектор.Если вы хотите «что-то сделать» или вернуть более 1 значения для каждого условия теста, if(){}else{} подходит.

0 голосов
/ 20 сентября 2018

Два комментария:

  • || - это короткое замыкание логического ИЛИ, оно не векторизовано и будет использовать только первый элемент.Если вы использовали переменные здесь, вы должны получить предупреждение об этом.
  • ifelse - это функция, а не управление потоком, поэтому вы должны присваивать ее значение переменной, а не пытаться выполнять присваивание внутри функцииаргументы.

Так что я думаю, что вы действительно хотите, выглядело бы больше как:

a <- b <- ifelse(1 == 1 | 2 == 2 | 3 == 3, 100, 1000)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...