Podczas pracy plyr
często uważałem, że przydatne jest użycie adply
funkcji skalarnych, które muszę zastosować do każdego wiersza.
na przykład
data(iris)
library(plyr)
head(
adply(iris, 1, transform , Max.Len= max(Sepal.Length,Petal.Length))
)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Max.Len
1 5.1 3.5 1.4 0.2 setosa 5.1
2 4.9 3.0 1.4 0.2 setosa 4.9
3 4.7 3.2 1.3 0.2 setosa 4.7
4 4.6 3.1 1.5 0.2 setosa 4.6
5 5.0 3.6 1.4 0.2 setosa 5.0
6 5.4 3.9 1.7 0.4 setosa 5.4
Teraz używam dplyr
więcej, zastanawiam się, czy istnieje uporządkowany / naturalny sposób na zrobienie tego? Ponieważ NIE tego chcę:
library(dplyr)
head(
mutate(iris, Max.Len= max(Sepal.Length,Petal.Length))
)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Max.Len
1 5.1 3.5 1.4 0.2 setosa 7.9
2 4.9 3.0 1.4 0.2 setosa 7.9
3 4.7 3.2 1.3 0.2 setosa 7.9
4 4.6 3.1 1.5 0.2 setosa 7.9
5 5.0 3.6 1.4 0.2 setosa 7.9
6 5.4 3.9 1.7 0.4 setosa 7.9
mdply
in dplyr, a hadley zasugerował, że mogą parzyć coś na podstawiedo
. Myślę, że to też by działało tutaj.rowwise()
co będzie grupowane według każdego wierszaadply
wtedy, gdy nie używasz grupowania? ponieważ jego ściśle zintegrowana funkcja nazywa sięgroup_by
NOTsplit_by
Odpowiedzi:
Od dplyr 0.2 (myślę)
rowwise()
jest zaimplementowany, więc odpowiedź na ten problem brzmi:Brak
rowwise
alternatywyPięć lat (!) Później ta odpowiedź jest nadal bardzo ruchliwa. Odkąd została podana,
rowwise
coraz częściej nie jest zalecana, chociaż wiele osób wydaje się uważać ją za intuicyjną. Zrób sobie przysługę i przejdź przez przepływy pracy Jenny Bryan zorientowane na Row w R z uporządkowanym materiałem, aby dobrze zrozumieć ten temat.Najprostszy sposób, jaki znalazłem, oparty jest na jednym z przykładów Hadleya z użyciem
pmap
:Korzystając z tego podejścia, możesz podać dowolną liczbę argumentów funkcji (
.f
) wewnątrzpmap
.pmap
jest dobrym podejściem koncepcyjnym, ponieważ odzwierciedla fakt, że wykonując operacje na wierszach, w rzeczywistości pracujesz z krotkami z listy wektorów (kolumnami w ramce danych).źródło
plyr
idplyr
, prawie na pewno używasz niewłaściwego,mutate
chyba że jawnie podasz zakresdplyr::mutate
.Idiomatycznym podejściem będzie stworzenie odpowiednio wektoryzowanej funkcji.
R
zapewnia,pmax
który jest tutaj odpowiedni, ale zapewnia równieżVectorize
jako opakowaniemapply
umożliwiające utworzenie wektoryzowanej dowolnej wersji dowolnej funkcji.Zauważ, że implementacja wektoryzacji w C / C ++ będzie szybsza, ale nie ma
magicPony
pakietu, który zapisze funkcję za Ciebie.źródło
dplyr
sposób ... jak byłoby prostsze bez dplyr npwith(df, Coalesce(a,b))
Być może, że jest to rodzaj odpowiedzi - nie używaćdplyr
do tego?magicPony
paczki. SzkodaMusisz pogrupować według wiersza:
Oto, co
1
zrobiliadply
.źródło
dplyr
ekspertem. Miejmy nadzieję, że ktoś inny przyjdzie z czymś lepszym. Uwaga: trochę go wyczyściłem1:n()
.group_by(1:n())
zachowanie. Jeśli nikt nie ma innych pomysłów rano, zaznaczę twój;)n
: „Ta funkcja jest zaimplementowana specjalnie dla każdego źródła danych i może być używana tylko z poziomu podsumowania.”, Chociaż wydaje się, że działa.Aktualizacja 2017-08-03
Po napisaniu tego Hadley ponownie zmienił kilka rzeczy. Funkcje, które kiedyś znajdowały się w mruczeniu, są teraz w nowym mieszanym pakiecie o nazwie purrrlyr , opisanym jako:
Będziesz więc musiał zainstalować + załadować ten pakiet, aby poniższy kod działał.
Oryginalny post
Hadley często zmienia zdanie na temat tego, czego powinniśmy użyć, ale myślę, że powinniśmy przełączyć się na funkcje w mruczeniu, aby uzyskać funkcjonalność według wiersza. Przynajmniej, oferują taką samą funkcjonalność i mają prawie taki sam interfejs jak
adply
z plyr .Istnieją dwie powiązane funkcje
by_row
iinvoke_rows
. Rozumiem, że używasz go,by_row
gdy chcesz zapętlić wiersze i dodać wyniki do data.frame.invoke_rows
jest używany, gdy zapętlasz wiersze data.frame i przekazujesz każdy col jako argument funkcji. Użyjemy tylko pierwszego.Przykłady
To pozwala nam zobaczyć elementy wewnętrzne (abyśmy mogli zobaczyć, co robimy), co jest tym samym, co robienie tego z
adply
.Domyślnie
by_row
dodaje kolumnę listy na podstawie wyniku:daje:
jeśli zamiast tego zwrócimy a
data.frame
, otrzymamy listę zdata.frame
s:daje:
Sposób dodawania danych wyjściowych funkcji jest kontrolowany przez
.collate
parametr. Dostępne są trzy opcje: lista, wiersze, kolumny. Kiedy nasze dane wyjściowe mają długość 1, nie ma znaczenia, czy używamy wierszy, czy kolumn.oba produkują:
Jeśli wyprowadzimy ramkę data.frame z 1 wierszem, liczy się tylko nieznacznie, którego użyjemy:
obie dają:
poza tym, że druga ma wywołaną kolumnę,
.row
a pierwsza nie.Wreszcie, jeśli nasze dane wyjściowe są dłuższe niż długość 1 jako a
vector
lub jako adata.frame
z wierszami, wtedy ma znaczenie, czy użyjemy wierszy, czy kolumn do.collate
:produkuje odpowiednio:
Tak więc, podsumowanie. Jeśli chcesz mieć
adply(.margins = 1, ...)
funkcjonalność, możesz użyćby_row
.źródło
by_row
jest przestarzały, wywołując go w celu „użyj kombinacji: tidyr :: nest (); dplyr :: mutate (); purrr :: map ()” github.com/hadley/purrrlyr/blob/…Rozszerzając odpowiedź BrodieG,
Jeśli funkcja zwraca więcej niż jeden wiersz
mutate()
,do()
należy użyć zamiast . Następnie, aby ponownie połączyć, użyjrbind_all()
zdplyr
opakowania.W
dplyr
wersjidplyr_0.1.2
używanie1:n()
wgroup_by()
klauzuli nie działa dla mnie. Miejmy nadzieję, że Hadleyrowwise()
wkrótce się wdroży .Testowanie wydajności,
ma następujące wyniki:
To pokazuje, że nowa
purrr
wersja jest najszybszaźródło
Coś takiego?
źródło
dplyr
rozwiązanie dla dowolnej funkcji skalarnej.wacky.function <- function(col.1, col.2){...}
, a potemiris.wacky <- wacky.function(iris$Sepal.Length, iris$Petal.Length)
.dplyr
lubplyr
lub mówiszdata.table
, powinieneś spróbować użyć ich idiomów, aby twój kod nie stał się trudnym do podzielenia się mieszanką stylów. Stąd pytanie.plyr
dokumentacji brzmi: „plyr to zestaw narzędzi, które rozwiązują typowy zestaw problemów: musisz rozbić duży problem na łatwe do zarządzania części, operować na każdym kawałku, a następnie złożyć wszystkie elementy razem”. Wydaje się, że to zupełnie inny problem, dla którego podstawowym narzędziem są operacje na kolumnach elementarnych. Może to również wyjaśniać, dlaczego nie ma „naturalnego” poleceniaplyr
/dplyr
do tego.