Я хочу создать функцию, которая сначала проверяет, что введенный вектор содержит только три символа "p", "s", "r" (в любом количестве или порядке). Я пробовал разные варианты:

  if (any (vec) != c("r", "p", "s")) {stop ("Inputs have to be rock, paper and scissors.")}

Подобно разделению условий с помощью |, но даже при наличии условия для одной буквы возвращает:

Error in if (any(vec) != c("r", "p", "s")) { : 
  missing value where TRUE/FALSE needed
In addition: Warning messages:
1: In any(vec) : coercing argument of type 'character' to logical
2: In if (any(vec) != c("r", "p", "s")) { :
  the condition has length > 1 and only the first element will be used

Люблю выяснять, почему R не рассматривает это как законное условие с ИСТИНА / ЛОЖЬ.

r
-1
Ronny Efronny 26 Ноя 2016 в 14:50

2 ответа

Лучший ответ

Причина в том, что условие возвращает логический вектор длины больше 1, а if/else работает с длиной 1. Измените условие на что-то вроде ниже, и оно будет работать

if(!any(vec %in% c("r", "p", "s"))) {
      stop ("Inputs have to be rock, paper and scissors.")}
#Error: Inputs have to be rock, paper and scissors.

Данные

vec <- c("a", "b")
4
akrun 26 Ноя 2016 в 11:55

Краткий ответ .

В вашем операторе if вы сравниваете any(vec) с вектором символов c("r", "p", "s"). Похоже, вы намеревались использовать функцию any после сравнения (т.е. просто следите за скобками). Что-то вроде этого - простое решение и, вероятно, именно то, что вы хотели:

if (any (vec != c("r", "p", "s"))) {stop ("Inputs have to be rock, paper and scissors.")}

Просмотрите сообщение об ошибке:

any - это функция, которая принимает логический (т. Е. TRUE или FALSE) ввод и возвращает логический вывод (он возвращает TRUE, если какой-либо из элементов входного вектора равен { {X4}}, иначе FALSE).

Первое предупреждающее сообщение связано с тем, что vec является символом, но поскольку R ожидает логического ввода для any, он пытается превратить (или принудить) ваш вектор символов в логический вектор (эквивалентно выполнению {{X2} }}). Это принуждение от символа к логическому приводит к NA, поскольку естественного способа сделать это не существует.

После вашего первого предупреждения R оценил any(vec), а вы следующим оцените NA != c("r", "p", "s"). Это производит NA NA NA, а оператор if ожидает логического ввода длины 1; Здесь появляется ваше второе предупреждение - R сообщает вам, что будет смотреть только на первый из трех элементов.

Ошибка возникает из-за того, что вы получаете if(NA), а NA не TRUE или FALSE, и не может быть принудительно к нему применен. Грубо говоря, вот что происходит, когда R оценивает ваш код.

if (any (vec) != c("r", "p", "s"))  #Original: Throws warning 1
if (NA != c("r", "p", "s"))         #Next
if (c(NA, NA, NA))                  #Throws warning 2
if (NA)                             #Throws error
1
hodgenovice 26 Ноя 2016 в 12:52