2011-01-01 19 views
13

W większości programowałem w Pythonie, ale teraz uczę się języka programowania statystycznego R. Zauważyłem pewną różnicę między językami, które mają tendencję do potknięcia się o mnie.Pułapki w R dla programistów Pythona

Załóżmy v jest wektorem/tablicę z liczb całkowitych od 1 do 5 włącznie.

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 

Czy są jeszcze jakieś inne pułapki, na które muszę uważać?

+2

'v [3]' w pythonie daje czwarty element sekwencji. w danym przypadku będzie to "4". – SilentGhost

+0

@SilentGhost: off course, naprawił błąd. – BioGeek

+2

Tytuł nie odzwierciedla dokładnie tutaj pytania - to nie są "pułapki w R", to tylko podstawowe różnice między dwoma różnymi językami. I tak, v [-1] nie "usuwa elementu" z indeksem 1, zwraca nowy wektor z każdym elementem oprócz pierwszego. – mdsumner

Odpowiedz

16

Po napisaniu dziesiątki tysięcy linii kodu w obu językach, R jest po prostu o wiele bardziej idiosynkratyczny i mniej spójny niż w Pythonie. Naprawdę miło jest robić szybkie wątki i badać na małym i średnim zestawie danych, głównie dlatego, że jego wbudowany obiekt danych jest ładniejszy niż odpowiednik numpy/scipy, ale znajdziesz wszystkie rodzaje dziwności, robiąc rzeczy bardziej skomplikowane niż jedna wkładka. Moja rada to użycie rpy2 (która niestety ma znacznie gorszy interfejs niż jego poprzednik, rpy) i po prostu robić tak mało jak to możliwe w R z resztą w Pythonie.

Na przykład rozważmy następujący kod matrix:

> 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 

Jak to nie? Powodem jest to, że jeśli wybierzesz submatrix z macierzy, która ma tylko jedną kolumnę wzdłuż danej osi, R "pomocnie" upuszcza tę kolumnę i zmienia typ zmiennej. Więc w jest wektorem liczb zamiast matrycy:

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

Aby tego uniknąć, trzeba rzeczywiście zdać niejasne parametru kluczowego:

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

Istnieje wiele zakamarków w tym stylu. Najlepszym przyjacielem na początku będzie introspekcja i narzędzia pomocy online, takie jak str, class, example i oczywiście help. Sprawdź również przykładowy kod na R Graph Gallery oraz w książce Ripley'a Modern Applied Statistics with S-Plus.


EDIT: Oto kolejny świetny przykład z czynników.

> 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 

Święta krowa! Przekształcenie czegoś z czynnika z powrotem na numeryczne nie spowodowało konwersji, którą myślałeś. Zamiast tego robi to na wewnętrznym, wyliczonym typie czynnika. Jest to źródło trudnych do znalezienia błędów dla osób, które nie są tego świadome, ponieważ wciąż zwracają liczby całkowite i faktycznie będą działać w danym czasie (gdy dane wejściowe są już uporządkowane numerycznie).

To jest to, co rzeczywiście trzeba zrobić

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

Tak, na pewno, że fakt, znajduje się na stronie factor pomóc, ale tylko tam wylądować, kiedy straciliśmy kilka godzin do tego błędu. Jest to kolejny przykład tego, jak R nie robi tego, co zamierzamy. Bądź bardzo, bardzo ostrożny przy wszystkim, co wymaga konwersji typu lub dostępu do elementów tablic i list.

+3

+1. Boże, nienawidzę tego domyślnego 'drop = TRUE'. – fabians

+0

Przykro mi, ale to szczególnie osobista opinia. W rzeczywistości nie można być szczęśliwym z niektórymi wartościami domyślnymi, lub uznać je za "mniej idiosynkratyczne", ale dla tego, co zostało zaprojektowane, R przewyższa Python w _my_ osobistej opinii. Po prostu przyzwyczaiłem się do tego, jak działa R, a ponieważ najczęściej wybierasz wiersz lub kolumnę z macierzy do wykonania ** wektoryzacji **, domyślny spadek = T nie jest wcale taki nielogiczny. –

+0

Cóż, oczywiście, ale możesz pomnożyć macierz n x 1 tak samo dobrze, jak możesz mieć długość n wektora. Nie ma powodu, by wymuszać konwersję typu. Zresztą, powiedzmy, nie jest to zachowanie w każdej innej biblioteki języka matryca (w tym numpy) i jest zatem istotne dla autora zapytania oryginalnego re: pułapek :) – ramanujan

1

Może być ... ale zanim zaczniesz, czy wypróbowałeś niektóre z dostępnych rozszerzeń Pythona? Scipy ma listę.

14

To nie jest specjalnie adresowania Python vs R tle, ale R inferno jest doskonałym źródłem informacji dla programistów, przybywających do R.

+3

+1 dla wskaźnika R Inferno - doskonałe odniesienie dla "pułapek" R " –

7

Przyjęta odpowiedź na to stanowisko jest prawdopodobnie nieco nieaktualna. Biblioteka Pythona Pandas zapewnia teraz niesamowitą obsługę podobną do R dla DataFrame.

Powiązane problemy