Интерпретация предупреждения "условие имеет длину> 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
Как я могу исправить функцию?
7 ответов
Может ты хочешь 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
if
утверждение не векторизовано. Для векторизованных операторов if следует использовать ifelse
, В вашем случае достаточно написать
w <- function(a){
if (any(a>0)){
a/sum(a)
}
else 1
}
или короткая векторизованная версия
ifelse(a > 0, a/sum(a), 1)
Это зависит от того, что вы хотите использовать, потому что первая функция дает выходной вектор длины 1 (в другой части) и ifelse
дает выходной вектор длины, равный длине a
,
Просто добавив пункт ко всей дискуссии о том, почему появляется это предупреждение (мне раньше было непонятно). Причина, по которой каждый получает это, как упоминалось ранее, заключается в том, что "a" в данном случае является вектором, а неравенство "a>0" создает другой вектор TRUE и FALSE (где "a" равно> 0 или нет).
Если вы хотите вместо этого протестировать любое значение "a>0", вы можете использовать функции - "any" или "all".
Лучший
Вот простой способ без 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
Использование lapply
Функция после создания вашей функции в обычном режиме.
lapply(x="your input", fun="insert your function name")
lapply
дает список, так что используйте unlist
функция, чтобы вывести их из функции
unlist(lapply(a,w))
Я пытался разобраться в этом вопросе, когда пытался сделать что-то похожее, когда определял функцию и вызывался с массивом, как указали другие.
Вы можете сделать что-то подобное, однако для этого сценария это менее элегантно по сравнению с методом Свена.
sapply(a, function(x) afunc(x))
afunc<-function(a){
if (a>0){
a/sum(a)
}
else 1
}
Я бы сказал, что наиболее эффективным способом является ответ пользователя 1317221_G. Однако, если вы хотите вернуться к основам, то цикл по длине вашего вектора (поскольку функция if не работает с длиной вектора) с использованием функции for был бы полезен.
w <- c() ##creates empty vector named 'w'
for(i in 1:length(a)){
if (a[i]>0){
w[i] <- a[i]/sum(a)
}
else
w[i] <- 1
}