Jestem samoukiem w R i to jest moje pierwsze pytanie StackOverflow. Przepraszam, jeśli to jest oczywisty problem; Proszę bądź uprzejmy.Powtórzyć mutację zmiennej przy użyciu dplyr i purrr
wersja skrócona moje pytanie
napisałem funkcję niestandardową obliczyć procentową zmianę w zmiennej roku na rok. Chciałbym użyć funkcji purrr
'map_at
, aby zastosować moją funkcję niestandardową do wektora nazw zmiennych. Mój zwyczaj funkcja działa po nałożeniu jednej zmiennej, ale nie powiedzie się, gdy łańcuch jest używany map_a
mój zwyczaj funkcja
calculate_delta <- function(df, col) {
#generate variable name
newcolname = paste("d", col, sep="")
#get formula for first difference.
calculate_diff <- lazyeval::interp(~(a + lag(a))/a, a = as.name(col))
#pass formula to mutate, name new variable the columname generated above
df %>%
mutate_(.dots = setNames(list(calculate_diff), newcolname)) }
Kiedy zastosować tę funkcję do pojedynczej zmiennej w zbiorze mtcars The wyjście jest zgodne z oczekiwaniami (chociaż oczywiście znaczenie wyniku nie ma sensu).
calculate_delta(mtcars, "wt")
Próbowano zastosować funkcję do postaci wektorowej Korzystanie Purrr
myślę, że mam problemy konceptualizacji jak map_at przechodzi argumentów do funkcji. Wszystkie przykładowe fragmenty, które mogę znaleźć w Internecie, używają map_at z funkcjami takimi jak is.character
, które nie wymagają dodatkowych argumentów. Oto moje próby zastosowania funkcji przy użyciu purrr
.
vars <- c("wt", "mpg")
mtcars %>% map_at(vars, calculate_delta)
To daje mi ten komunikat o błędzie
Error in paste("d", col, sep = "") : argument "col" is missing, with no default
zakładam to dlatego map_at przechodzi vars
jako df
, a nie przekazując argument dla col
. Aby obejść ten problem, próbowałem następujące:
vars <- c("wt", "mpg")
mtcars %>% map_at(vars, calculate_delta, df = .)
To rzuca mi ten błąd:
Error: unrecognised index type
Mam monkeyed dokoła z gronem różnych wersjach, w tym usunięcie df
argumentu z calculate_delta
Funkcja, ale nie miałem szczęścia.
innych możliwych rozwiązań
1) Wersja z użyciem sapply
, zamiast purrr
. Próbowałem rozwiązać problem w ten sposób i miałem podobne problemy. Moim celem jest znalezienie sposobu na zrobienie tego za pomocą purrr, jeśli to możliwe. W oparciu o moje zrozumienie purrr
wydaje się, że jest to typowy przypadek użycia.
2) Mogę oczywiście wymyślić, jak zaimplementowałem to za pomocą pętli for, ale staram się tego uniknąć, jeśli to możliwe z podobnych powodów.
Najwyraźniej myślę o tym źle. Proszę pomóż!
EDIT 1
Aby wyjaśnić, jestem ciekaw, czy istnieje metoda wielokrotnie transformacji zmiennych, które realizuje dwie rzeczy.
1) Generuje nowe zmienne w oryginalnym numerze tbl_df
bez zastępowania kolumn zamienianych (tak jak w przypadku korzystania z dplyr
z mutate_at
).
2) Automatycznie generuje nowe etykiety zmiennych.
3) Jeśli to możliwe, wykonaj to, co opisałem, stosując jedną funkcję, używając map_at
.
Możliwe, że nie jest to możliwe, ale wydaje mi się, że powinien istnieć elegancki sposób na osiągnięcie tego, co opisuję.
Twoja funkcja nie jest gotowa do umieszczenia w strukturze "mutate" lub podobnej. Spróbuj 'mtcars%>% mutate (calcul_delta (wt))', aby zobaczyć, że nawet bez 'purrr' lub' map' nie działa. Jeśli nie działa z normalnym wywołaniem 'dplyr', to nie zadziała w tej strukturze. Powinien zostać ponownie napisany. Możesz zacząć od usunięcia konieczności specyfikacji ramki danych. Pomyśl o tym, jak "suma" lub "średnia" nie wymagają ramek danych w ramach połączenia, są zbudowane dla wektorów. –
Dziękujemy, jest to pomocny sposób na przemyślenie tego problemu. Ta funkcja, z @PierreLafortune poniżej, działa jako część wywołania mutacji dplyr: 'delta <- funkcja (x) (x + dplyr :: lag (x))/x' i działa również z' purrr'. Jak już wspomniałem, część, która mnie wyzwala, dynamicznie zmienia nazwę zmiennych. –