Подтвердить что ты не робот

Интерпретация "имеет длину> 1" предупреждение от функции `if`

У меня есть массив:

a <- c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

и хотел бы реализовать следующую функцию:

w<-function(a){
  if (a>0){
    a/sum(a)
  }
  else 1
}

Эта функция хотела бы проверить, есть ли какое-либо значение в a больше 0, и если да, то разделите каждый элемент на сумму суммы.

В противном случае он должен просто записать 1.

Появляется следующее предупреждающее сообщение:

 Warning message:
 In if (a > 0) { :
 the condition has length > 1 and only the first element will be used

Как я могу исправить функцию?

4b9b3361

Ответ 1

возможно, вы хотите ifelse:

a <- c(1,1,1,1,0,0,0,0,2,2)
ifelse(a>0,a/sum(a),1)

 [1] 0.125 0.125 0.125 0.125 1.000 1.000 1.000 1.000
 [9] 0.250 0.250

Ответ 2

Оператор

if не векторизован. Для векторизованных операторов if вы должны использовать ifelse. В вашем случае достаточно написать

w <- function(a){
if (any(a>0)){
  a/sum(a)
}
  else 1
}

или короткая версия с векторизованной версией

ifelse(a > 0, a/sum(a), 1)

Это зависит от того, что вы хотите использовать, потому что первая функция дает выходной вектор длины 1 (в части else) и ifelse дает выходной вектор длины, равный длине a.

Ответ 3

Здесь простой способ без ifelse:

(a/sum(a))^(a>0)

Пример:

a <- c(0, 1, 0, 0, 1, 1, 0, 1)

(a/sum(a))^(a>0)

[1] 1.00 0.25 1.00 1.00 0.25 0.25 1.00 0.25

Ответ 4

Просто добавив точку в целом дискуссию о том, почему это предупреждение появляется (раньше мне это не было ясно). Причина, по которой это делается, как упоминалось ранее, заключается в том, что "a" в этом случае является вектором, а неравенство "a > 0" создает другой вектор TRUE и FALSE (где "a" → 0 или нет).

Если вы хотите вместо этого проверить, есть ли какое-либо значение 'a > 0', вы можете использовать функции - "any" или "all"

Лучшие

Ответ 5

Способ, которым я был в курсе этого вопроса, состоял в том, что я пытался сделать что-то подобное, когда я определял функцию, и он вызывался с массивом, как и другие, указывающие

Вы можете сделать что-то подобное, но для этих сценариев это менее элегантно по сравнению с методом Свена.

sapply(a, function(x) afunc(x))

afunc<-function(a){
  if (a>0){
    a/sum(a)
  }
  else 1
}

Ответ 6

Используйте функцию lapply после создания вашей функции в обычном режиме.

lapply(x="your input", fun="insert your function name")

lapply дает список, поэтому используйте функцию unlist чтобы вывести их из функции

unlist(lapply(a,w))