J'essaie d'utiliser dplyr :: filter ()
avec NSE, mais je ne peux pas le faire fonctionner lorsque la variable filtrée est as.Date ()
.
Voici la fonction qui fonctionne presque:
foo2 <- function(d, f, var) { d %>% filter(!!var >= f) } #foo2(d, f=5, var="a") #foo2(d, f="2019-01-05", var="a")
Mais si a
est une date ça ne fonctionnera pas:
XXX
J'ai également essayé ceci:
d <- data.frame(a=seq.Date(as.Date("2019-01-01"), length.out = 7, by="day"), b=1) foo(d, f=as.Date("2019-01-05"), var="a") # or foo(d, f="2019-01-05", var="a") # a b # 1 2019-01-01 1 # 2 2019-01-02 1 # 3 2019-01-03 1 # 4 2019-01-04 1 # 5 2019-01-05 1 # 6 2019-01-06 1 # 7 2019-01-07 1
Ce qui ne fonctionne pas dans les deux cas, je suis intéressé de savoir pourquoi foo2
cela ne fonctionne pas.
3 Réponses :
Vous n'avez pas besoin de Résultat: !!
( rlang ::
). Insérez var
dans as.name
(ou as.symbol
) pour en faire un symbole, puis utilisez eval () code > à l'intérieur du
filtre
pour évaluer l'objet dans l'environnement de la fonction: > foo2(d, f="2019-01-05", var="a")
a b
1 2019-01-05 1
2 2019-01-06 1
3 2019-01-07 1
library(magrittr)
library(dplyr)
d <- data.frame(a=seq.Date(as.Date("2019-01-01"), length.out = 7, by="day"), b=1)
foo2 <- function(d, f, var) {
sym <- as.name(var)
d %>%
filter(eval(sym) >= f)
}
essayez de transmettre l'argument var
pas comme une chaîne. dans ce cas, vous devez changer la fonction foo
en:
foo <- function(d, f, var) { var <- enquo(var) d %>% filter(!!var >= f) } foo(d, f=as.Date("2019-01-05"), var=a)
Ne modifiez pas votre fonction. Concentrons-nous sur le code
foo(d, f = unclass(as.Date("2019-01-05")), var = "a") # a b # 1 2019-01-05 1 # 2 2019-01-06 1 # 3 2019-01-07 1
Si l'entrée f
est une Date
, l'instruction paste0 (var, "> = ", f)
dans votre fonction renverra
" a> = 2019-01-05 " (Cela signifie la colonne a est supérieur et égal à "2019-01-05"
, qui est une chaîne de caractères et non une date car les sorties de paste ()
sont toujours des caractères)
L'instruction ci-dessus n'est pas significative car les chaînes de caractères ne peuvent pas être comparées. Vous devez donc transformer la date d'entrée en numérique par unclass ()
ou as.numeric ()
tel que
foo(d, f = unclass(as.Date("2019-01-05")), var = "a")
et l'instruction renverra "a> = 17901"
, qui est une instruction logique normale.
Sortie
foo(d, f = as.Date("2019-01-05"), var = "a")
Notez que "a> = 17901" réussira car les dates (colonne a
) peuvent être par rapport aux chiffres ( 17910
).
Puisque vous passez le nom de la variable sous forme de chaîne, vous voudrez quelque chose comme
ensym ()
autour devar
dans votre fonction. Commevar = ensym (var)
avant la lignefilter ()
. Ensuite, les choses devraient fonctionner pour les dates si vous passezf
une valeur viaas.Date ()
.Merci, cela fonctionne avec
foo2
, voulez-vous publier comme réponse?