Interpretatie “voorwaarde heeft lengte > 1” waarschuwing van de functie `if`

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 adie 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 ifelsegebruiken. 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 ifelsegeeft 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 lapplynadat u uw functie normaal hebt gemaakt.

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

lapplygeeft een lijst, dus gebruik unlistfunctie om ze uit de functie

te halen

unlist(lapply(a,w))

Other episodes