Chcę użyć dplyr::mutate()
do utworzenia wielu nowych kolumn w ramce danych. Nazwy kolumn i ich zawartość powinny być generowane dynamicznie.
Przykładowe dane z tęczówki:
library(dplyr)
iris <- tbl_df(iris)
Utworzyłem funkcję do mutowania moich nowych kolumn ze Petal.Width
zmiennej:
multipetal <- function(df, n) {
varname <- paste("petal", n , sep=".")
df <- mutate(df, varname = Petal.Width * n) ## problem arises here
df
}
Teraz tworzę pętlę do budowania moich kolumn:
for(i in 2:5) {
iris <- multipetal(df=iris, n=i)
}
Jednak ponieważ mutate myśli, że nazwa_zmiennej jest dosłowną nazwą zmiennej, pętla tworzy tylko jedną nową zmienną (nazywaną nazwa_zmiennej) zamiast czterech (nazywana płatkiem.2 - płatek.5).
Jak mogę mutate()
użyć mojej dynamicznej nazwy jako nazwy zmiennej?
dplyr
ma całą winietę na niestandardową ocenęmutate_
, a z innych funkcji naprawdę nie wynika, jak z niej korzystać.Odpowiedzi:
Ponieważ dynamicznie budujesz nazwę zmiennej jako wartość znakową, bardziej sensowne jest wykonywanie przypisania przy użyciu standardowego indeksowania data.frame, które pozwala na wartości znakowe dla nazw kolumn. Na przykład:
mutate
Funkcja sprawia, że bardzo łatwo wymienić nowe kolumny za pośrednictwem nazwanych parametrów. Ale to zakłada, że znasz nazwę po wpisaniu polecenia. Jeśli chcesz dynamicznie określić nazwę kolumny, musisz także zbudować nazwany argument.wersja dplyr> = 0,7
Najnowsza wersja
dplyr
(0.7) robi to, używając:=
do dynamicznego przypisywania nazw parametrów. Możesz zapisać swoją funkcję jako:Aby uzyskać więcej informacji, zobacz dostępny formularz dokumentacji
vignette("programming", "dplyr")
.dplyr (> = 0,3 i <0,7)
Nieco wcześniejsza wersja
dplyr
(> = 0.3 <0.7), zachęcała do stosowania alternatyw „standardowej oceny” dla wielu funkcji. Zobacz winietę oceny niestandardowej, aby uzyskać więcej informacji (vignette("nse")
).Więc tutaj odpowiedź brzmi: użyj
mutate_()
zamiastmutate()
i wykonaj:dplyr <0,3
Zauważ, że jest to również możliwe w starszych wersjach,
dplyr
które istniały, gdy pierwotnie zadawano pytanie. Wymaga starannego użytkowaniaquote
isetName
:źródło
do.call()
prawdopodobnie nie robi tego, co myślisz, że robi: rpubs.com/hadley/do-call2 . Zobacz także winietę nse w wersji deweloperskiej programu dplyr.do.call
powyższe, aby używaćdo.call("mutate")
i cytowaćdf
na liście. Czy to właśnie sugerowałeś? A kiedylazyeval
wersjadplyr
jest wydaną wersją,mutate_(df, .dots= setNames(list(~Petal.Width * n), varname))
czy byłoby lepszym rozwiązaniem?mutate(df, !!newVar := (!!var1 + !!var2) / 2)
nie działa :(W nowej wersji
dplyr
(0.6.0
oczekiwanej w kwietniu 2017) możemy również wykonać przypisanie (:=
) i przekazać zmienne jako nazwy kolumn przez unquoting (!!
), aby ich nie oceniaćSprawdzanie wyjścia w oparciu o @ MrFlick
multipetal
zastosowane na 'iris1'źródło
Po wielu próbach i błędach stwierdziłem, że wzorzec jest
UQ(rlang::sym("some string here")))
naprawdę przydatny do pracy z ciągami znaków i czasownikami dplyr. Wydaje się, że działa w wielu zaskakujących sytuacjach.Oto przykład z
mutate
. Chcemy stworzyć funkcję, która zsumuje dwie kolumny, w której przekazujesz funkcję obie nazwy kolumn jako ciągi. Aby to zrobić, możemy użyć tego wzorca wraz z operatorem przypisania:=
.Wzór działa również z innymi
dplyr
funkcjami. Otofilter
:Lub
arrange
:Na
select
, nie trzeba korzystać z wzorca. Zamiast tego możesz użyć!!
:źródło
myCol
na adres URL (na przykład) imyColInitialValue
kopiuję starą kolumnę na końcu ramki danychdf
z nową nazwą. Alewhich(colnames(df)=='myCol')
odeślij col # zmyColInitialValue
. Nie napisałem jeszcze problemu, ponieważ nie znalazłem reprexu. Moim celem jest dlaescape
parametruDT::datatable()
. Używamescape=FALSE
w oczekiwaniu, że. Ze stałymi to również nie działa, ale pakiet DT wydaje się również mieć złą kolumnę #. :)escape
zDT::datatable
varname = sym("Petal.Width"); ggplot(iris, aes(x=!!varname)) + geom_histogram()
Oto inna wersja, prawdopodobnie nieco prostsza.
źródło
Dzięki temu
rlang 0.4.0
mamy operatory curly-curly ({{}}
), co bardzo ułatwia to zadanie.Możemy również przekazywać nazwy zmiennych w cudzysłowie / niecytowane, aby były przypisane jako nazwy kolumn.
Działa tak samo z
źródło
Dodam też odpowiedź, która trochę to powiększa, bo doszedłem do tego wpisu szukając odpowiedzi, a ten miał prawie to, czego potrzebowałem, ale potrzebowałem trochę więcej, co dostałem przez odpowiedź @MrFlik i R leniwe winiety.
Chciałem stworzyć funkcję, która mogłaby pobierać ramkę danych i wektor nazw kolumn (jako ciągi znaków), które chcę przekonwertować z ciągu na obiekt Date. Nie mogłem wymyślić, jak zrobić
as.Date()
argument, który jest ciągiem i przekonwertować go na kolumnę, więc zrobiłem to, jak pokazano poniżej.Poniżej jest jak to zrobiłem za pomocą SE mutate (
mutate_()
) i.dots
argument. Krytyka, która to poprawia, jest mile widziana.źródło
Chociaż lubię używać dplyr do użytku interaktywnego, uważam to za niezwykle trudne za pomocą dplyr, ponieważ musisz przejść przez obręcze, aby użyć obejść lazyeval :: interp (), setNames itp.
Oto prostsza wersja wykorzystująca bazę R, w której wydaje mi się bardziej intuicyjne, przynajmniej dla mnie, umieszczenie pętli wewnątrz funkcji i która rozszerza rozwiązanie @ MrFlicks.
źródło
dplyr
dużo używam w ustawieniach nieinteraktywnych, używanie go z zmiennym wejściem wewnątrz funkcji wymaga bardzo niezgrabnej składni.Możesz cieszyć się pakietem,
friendlyeval
który zawiera uproszczone, uporządkowane API i dokumentację dla nowszych / zwykłychdplyr
użytkowników.Tworzysz łańcuchy, które chcesz
mutate
traktować jako nazwy kolumn. Więc używającfriendlyeval
możesz napisać:Które pod maską wywołuje
rlang
funkcje, które sprawdzają, czyvarname
jest legalne jako nazwa kolumny.friendlyeval
kod można w dowolnym momencie przekonwertować na równoważny zwykły, uporządkowany kod eval za pomocą dodatku RStudio.źródło