2011-01-01 12 views
13

Ho programmato principalmente in Python, ma ora sto imparando il linguaggio di programmazione statistica R. Ho notato alcune differenze tra i linguaggi che tendono a inciampare.Insidie ​​in programmatori R per Python

Supponiamo che v sia un vettore/array con i numeri interi compresi tra 1 e 5 inclusi.

v[3] # in R: gives me the 3rd element of the vector: 3 
     # in Python: is zero-based, gives me the integer 4 
v[-1] # in R: removes the element with that index 
     # in Python: gives me the last element in the array 

Ci sono altre insidie ​​a cui devo fare attenzione?

+2

'v [3]' in python fornisce il quarto elemento di una sequenza. nel caso specifico sarebbe '4'. – SilentGhost

+0

@SilentGhost: fuori rotta, risolto l'errore. – BioGeek

+2

Il titolo non rappresenta esattamente la domanda qui - queste non sono "insidie ​​in R", sono solo differenze fondamentali tra due lingue diverse. E comunque, v [-1] non "rimuove l'elemento" con l'indice 1, restituisce un nuovo vettore con ogni elemento tranne il primo. – mdsumner

risposta

16

Dopo aver scritto decine di migliaia di righe di codice in entrambe le lingue, R è solo molto più idiosincratico e meno coerente di Python. È davvero utile per fare grafici veloci e indagini su un set di dati di piccole e medie dimensioni, principalmente perché il suo oggetto dataframe incorporato è più bello dell'equivalente numpy/scipy, ma troverai tutti i tipi di stranezze mentre fai cose più complicate di un rivestimento. Il mio consiglio è di usare rpy2 (che sfortunatamente ha un'interfaccia utente molto peggiore del suo predecessore, rpy) e fare il meno possibile in R con il resto in Python.

Ad esempio, si consideri il seguente codice a matrice:

> u = matrix(1:9,nrow=3,ncol=3) 
> v = u[,1:2] 
> v[1,1] 
[2] 1 
> w = u[,1] 
> w[1,1] 
Error in w[1, 1] : incorrect number of dimensions 

Come ha fatto che fallire? La ragione è che se si seleziona una sottomatrice da una matrice che ha solo una colonna lungo un dato asse, R "utilizza" in modo appropriato la colonna e cambia il tipo della variabile. Quindi w è un vettore di interi piuttosto che una matrice:

> class(v) 
[1] "matrix" 
> class(u) 
[1] "matrix" 
> class(w) 
[1] "integer" 

Per evitare questo, è necessario passare in realtà un parametro parola chiave oscura:

> w2 = u[,1,drop=FALSE] 
> w2[1,1] 
[3] 1 
> class(w2) 
[1] "matrix" 

C'è un sacco di angoli e fessure del genere. Il tuo migliore amico all'inizio sarà introspezione e strumenti di aiuto online come str, class, example e, naturalmente, help. Inoltre, assicurati di guardare il codice di esempio su R Graph Gallery e nel libro Modern Applied Statistics with S-Plus di Ripley.


EDIT: Ecco un altro grande esempio con fattori.

> xx = factor(c(3,2,3,4)) 
> xx 
[1] 3 2 3 4 
Levels: 2 3 4 
> yy = as.numeric(xx) 
> yy 
[1] 2 1 2 3 

Holy cow! La conversione di un elemento da un fattore indietro a un valore numerico non ha effettivamente effettuato la conversione che avresti pensato. Invece lo fa sul tipo enumerato interno del fattore. Questa è una fonte di bug difficili da trovare per le persone che non ne sono a conoscenza, perché sta ancora restituendo numeri interi e infatti funzionerà effettivamente del tempo (quando l'input è già ordinato numericamente).

Questo è ciò che è effettivamente necessario fare

> as.numeric(levels(xx))[xx] 
[1] 3 2 3 4 

Sì, certo, che infatti si trova nella pagina factor aiuto, ma si terra solo fino lì quando hai perso un paio d'ore a questo bug. Questo è un altro esempio di come R non fa ciò che tu intendi. Sii molto, molto attento a tutto ciò che riguarda le conversioni di tipo o l'accesso a elementi di array e liste.

+3

+1. Dio, odio il valore predefinito di "drop = TRUE". – fabians

+0

Mi dispiace, ma è soprattutto un'opinione personale. In effetti, non si può essere contenti di alcune impostazioni predefinite o trovarle "meno idiosincratiche", ma per quello che è stato progettato, R ottiene prestazioni migliori rispetto a Python in _my_ parere personale. Mi sono appena abituato a come funziona R, e come più spesso selezioni una riga o una colonna da una matrice per eseguire un calcolo ** vettorializzato **, la caduta predefinita = T non è tutto ciò che non è logico. –

+0

Beh, certo, ma puoi moltiplicare una matrice n x 1 altrettanto bene che puoi un vettore di lunghezza n. Non c'è motivo di forzare una conversione di tipo. In ogni caso, diciamo che questo non è il comportamento in qualsiasi altra libreria di matrici (incluso numpy) ed è quindi pertinente alla domanda originale dell'autore re: insidie ​​:) – ramanujan

1

Ci può essere ... ma prima di imbarcarti hai provato alcune delle estensioni Python disponibili? Scipy ha una lista.

14

questo non è specificatamente legati Python vs R sfondo, ma il R inferno è una grande risorsa per i programmatori che vengono a R.

+3

+1 per R Puntatore inferno - un ottimo riferimento per le "trappole" R –

7

La risposta accettata a questo post è forse un po 'obsoleta. La libreria Python Pandas ora offre un incredibile supporto DataFrame simile a R.

Problemi correlati