2013-07-15 9 views
8

In uno script più lungo devo moltiplicare la lunghezza di un vettore A (2614) con il numero di righe di un dataframe B (1456000). Se lo faccio direttamente con length(A) * nrow(B) ricevo il messaggio NAs produced by integer overflow anche se non c'è nessun problema quando moltiplico gli stessi numeri:R: la semplice moltiplicazione causa l'overflow di numeri interi

2614 * 1456000 
[1] 3805984000 

L'unico modo per ottenere la moltiplicazione di lavoro è round(length(A)) * nrow(B) o length(A) * round(nrow(B)). Ma i numeri prodotti da length e nrow devono essere comunque interi! Inoltre, ho provato questo con la seguente funzione suggerito nella pagina di aiuto per la funzione is.integer ...

is.wholenumber <- function(x, tol = .Machine$double.eps^0.5) abs(x-round(x)) < tol 

... e, naturalmente, sono numeri interi. Allora, perché ho bisogno delle "stampelle" qui? Molto sconcertante ... Qualcuno ha un'idea di cosa sta succedendo in sottofondo?

+2

'2614 * 1456000' sono ** ** non intero ...'> classe (1.456.000) [1] "numerico" > classe (1456000L) [1] "integer" ' – Michele

+0

@Michele grazie, Ho aggiornato la mia risposta un po 'a causa di questo commento. –

risposta

10

Speriamo che una rappresentazione grafica di ciò che accade ....

2614 * 1456000 
#[1] 3805984000 

## Integers are actually represented as doubles 
class(2614 * 1456000) 
#[1] "numeric" 

# Force numbers to be integers 
2614L * 1456000L 
#[1] NA 
#Warning message: 
#In 2614L * 1456000L : NAs produced by integer overflow 

## And the result is an integer with overflow warning 
class(2614L * 1456000L) 
#[1] "integer" 
#Warning message: 
#In 2614L * 1456000L : NAs produced by integer overflow 

2614 * 1456000 è un numeric perché entrambi gli operandi sono in realtà di classe numeric. L'overflow si verifica perché entrambi nrow e length restituiscono integer e quindi il risultato è un numero intero ma il risultato supera la dimensione massima rappresentabile dalla classe integer (+/- 2 * 10^9). Un numeric o double può contenere 2e-308 to 2e+308. Quindi per risolvere il tuo problema, usa solo as.numeric(length(A)) o as.double(length(A)).

Problemi correlati