Ik heb een array:
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)
en zou graag de volgende functie willen implementeren:
w<-function(a){
if (a>0){
a/sum(a)
}
else 1
}
Deze functie wil controleren of er een waarde is in a
die groter is dan 0 en zo ja, deel dan elk element door de som van het totaal.
Anders zou het gewoon 1 moeten opnemen.
Ik krijg het volgende waarschuwingsbericht:
Warning message:
In if (a > 0) { :
the condition has length > 1 and only the first element will be used
Hoe kan ik de functie corrigeren?
Antwoord 1, autoriteit 100%
misschien wil je 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
Antwoord 2, autoriteit 77%
if
-instructie is niet gevectoriseerd. Voor gevectoriseerde if-statements moet je ifelse
gebruiken. In jouw geval is het voldoende om te schrijven
w <- function(a){
if (any(a>0)){
a/sum(a)
}
else 1
}
of een korte gevectoriseerde versie
ifelse(a > 0, a/sum(a), 1)
Het hangt ervan af welke u wilt gebruiken, want de eerste functie geeft een uitvoervector van lengte 1 (in else part) en ifelse
geeft een uitvoervector met een lengte gelijk aan de lengte van a
.
Antwoord 3, autoriteit 33%
Hier is een gemakkelijke manier zonder ifelse
:
(a/sum(a))^(a>0)
Een voorbeeld:
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
Antwoord 4, autoriteit 32%
Gewoon een punt toevoegen aan de hele discussie over waarom deze waarschuwing verschijnt (het was me niet eerder duidelijk). De reden waarom men dit krijgt is zoals eerder vermeld, omdat ‘a’ in dit geval een vector is en de ongelijkheid ‘a>0’ een andere vector van TRUE en FALSE produceert (waarbij ‘a’ >0 is of niet).
Als u in plaats daarvan een waarde van ‘a>0’ wilt testen, kunt u functies gebruiken – ‘any’ of ‘all’
Beste
Antwoord 5, autoriteit 5%
De manier waarop ik deze vraag tegenkwam, was toen ik iets soortgelijks probeerde te doen waarbij ik een functie definieerde en deze werd aangeroepen met de array zoals anderen al zeiden
Je zou zoiets kunnen doen, maar voor deze scenario’s is het minder elegant in vergelijking met de methode van Sven.
sapply(a, function(x) afunc(x))
afunc<-function(a){
if (a>0){
a/sum(a)
}
else 1
}
Antwoord 6, autoriteit 3%
Gebruik de functie lapply
nadat u uw functie normaal hebt gemaakt.
lapply(x="your input", fun="insert your function name")
lapply
geeft een lijst, dus gebruik unlist
functie om ze uit de functie
te halen
unlist(lapply(a,w))