2013-01-05 12 views
21

Ho un array:Interpretazione "condizione ha lunghezza> 1" avvertimento da `if` funzione

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) 

e vorrei implementare la seguente funzione:

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

Questa funzione vorrebbe controlla se c'è un valore in a maggiore di 0 e se sì allora dividi ogni elemento per la somma del totale.

In caso contrario si deve solo registrare 1.

ricevo il seguente messaggio di avviso:

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

Come posso correggere la funzione?

+0

@ user1723765 cosa ti aspetti di avere? – agstudy

+1

quindi in pratica se aa [a> 0] allora a/sum (a) dovrebbe essere fatto, non a [a> 0]/sum (a) – user1723765

+0

il risultato sarebbe 0s e .166667 ecc per gli altri numeri ma vorrei alla fine ho ancora l'intero vettore – user1723765

risposta

37

forse si vuole 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 
30

if affermazione non è vettorializzare. Per le dichiarazioni vettoriali se è necessario utilizzare ifelse. Nel tuo caso, è sufficiente scrivere

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

o una breve versione Vectorised

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

Dipende da quale vuoi usare, perché prima funzione fornisce in uscita vettore di lunghezza 1 (in parte il resto) e ifelse fornisce un vettore di uscita di lunghezza uguale alla lunghezza di a.

+10

perché oh perché, se tutto il resto in R-land è vettorizzato ... 'se' non lo è? SMDH. –

14

Ecco un modo semplice senza ifelse:

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

Un esempio:

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

Batte 'ifelse' di circa un fattore di 7 (su un array di elementi 100000). –

+0

Buono a sapersi, @Arun +1 –

+0

Potresti raccomandare una breve spiegazione/documentazione di questo operatore '^' (ad esempio, come si chiama e come funziona). Preferibilmente qualcosa di più semplice della documentazione [Arithmetic Operators] (https://stat.ethz.ch/R-manual/R-devel/library/base/html/Arithmetic.html) ... – theforestecologist

7

Solo l'aggiunta di un punto per l'intera discussione sul motivo per cui questo avvertimento viene in su (Non è chiaro a io prima). Il motivo per cui si ottiene questo è come detto prima è perché 'a' in questo caso è un vettore e l'ineguaglianza 'a> 0' produce un altro vettore di VERO e FALSO (dove 'a' è> 0 o meno).

Se volete provare, invece, se ogni valore di 'a> 0', è possibile utilizzare le funzioni - 'qualsiasi' o 'all'

Miglior

0

il mio modo di cam attraverso questa domanda era quando ho provato a fare qualcosa di simile dove stavo definendo una funzione e veniva chiamato con la matrice come altri hanno sottolineato

Si potrebbe fare qualcosa di simile, tuttavia per questi scenari è meno elegante rispetto al metodo di Sven.

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

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