Ответ 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
У меня есть массив:
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
Как я могу исправить функцию?
возможно, вы хотите 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 (в части else) и ifelse
дает выходной вектор длины, равный длине a
.
Здесь простой способ без 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
Просто добавив точку в целом дискуссию о том, почему это предупреждение появляется (раньше мне это не было ясно). Причина, по которой это делается, как упоминалось ранее, заключается в том, что "a" в этом случае является вектором, а неравенство "a > 0" создает другой вектор TRUE и FALSE (где "a" → 0 или нет).
Если вы хотите вместо этого проверить, есть ли какое-либо значение 'a > 0', вы можете использовать функции - "any" или "all"
Лучшие
Способ, которым я был в курсе этого вопроса, состоял в том, что я пытался сделать что-то подобное, когда я определял функцию, и он вызывался с массивом, как и другие, указывающие
Вы можете сделать что-то подобное, но для этих сценариев это менее элегантно по сравнению с методом Свена.
sapply(a, function(x) afunc(x))
afunc<-function(a){
if (a>0){
a/sum(a)
}
else 1
}
Используйте функцию lapply
после создания вашей функции в обычном режиме.
lapply(x="your input", fun="insert your function name")
lapply
дает список, поэтому используйте функцию unlist
чтобы вывести их из функции
unlist(lapply(a,w))