2015-01-17 13 views
6

Esiste comunque una stringa per passare come riferimento di colonna a una procedura dplyr?dplyr stringa come riferimento colonna

Ecco un esempio: con un set di dati raggruppati e una funzione semplice in cui provo a passare una stringa come riferimento a una colonna. Grazie!

machines <- data.frame(Date=c("1/31/2014", "1/31/2014", "2/28/2014", "2/28/2014", "3/31/2014", "3/31/2014"), 
      Model.Num=c("123", "456", "123", "456", "123", "456"), 
      Cost=c(200, 300, 250, 350, 300, 400)) 

my.fun <- function(data, colname){ 
    mutate(data, position=cumsum(as.name(colname))) 
} 

machines <- machines %>% group_by(Date, Model.Num)  
machines <- my.fun(machines, "Cost") 
+1

Si dovrebbe leggere la vignetta nse ('vignette (" nse ", package =" dplyr ")', si rivolge esattamente a questa situazione. – Ista

risposta

7

Ecco un'opzione che utilizza interp() dal pacchetto lazyeval, che è venuto con il vostro dplyr installare. All'interno della/e funzione/e, è necessario utilizzare la versione di valutazione standard delle funzioni dplyr. In questo caso sarebbe mutate_().

Si noti che la nuova colonna position sarà identica alla colonna Cost qui a causa di come è stato impostato il raggruppamento in machines. La seconda chiamata a my_fun() mostra che funziona su un diverso insieme di variabili di raggruppamento.

library(dplyr) 
library(lazyeval) 

my_fun <- function(data, col) { 
    mutate_(data, position = interp(~ cumsum(x), x = as.name(col))) 
} 

my_fun(machines, "Cost") 
#  Date Model.Num Cost position 
# 1 1/31/2014  123 200  200 
# 2 1/31/2014  456 300  300 
# 3 2/28/2014  123 250  250 
# 4 2/28/2014  456 350  350 
# 5 3/31/2014  123 300  300 
# 6 3/31/2014  456 400  400 

## second example - different grouping 
my_fun(group_by(machines, Model.Num), "Cost") 
#  Date Model.Num Cost position 
# 1 1/31/2014  123 200  200 
# 2 1/31/2014  456 300  300 
# 3 2/28/2014  123 250  450 
# 4 2/28/2014  456 350  650 
# 5 3/31/2014  123 300  750 
# 6 3/31/2014  456 400  1050 
0

Siamo in grado di valutare nella valutazione standard senza l'utilizzo di lazyeval pacchetto. Possiamo impostare una stringa come nome della variabile usando setNames.

library(tidyverse) 

machines <- data.frame(
    Date = c("1/31/2014", "1/31/2014", "2/28/2014", "2/28/2014", "3/31/2014", "3/31/2014"), 
    Model.Num = c("123", "456", "123", "456", "123", "456"), 
    Cost = c(200, 300, 250, 350, 300, 400) 
) 

my_fun <- function(data, col) { 
    mutate_(data, .dots = setNames(paste0("cumsum(", col, ")"), "position")) 
} 

my_fun(machines %>% group_by(Date, Model.Num), "Cost") 
# Source: local data frame [6 x 4] 
# Groups: Date, Model.Num [6] 
# 
# Date Model.Num Cost position 
# <fctr> <fctr> <dbl> <dbl> 
# 1 1/31/2014  123 200  200 
# 2 1/31/2014  456 300  300 
# 3 2/28/2014  123 250  250 
# 4 2/28/2014  456 350  350 
# 5 3/31/2014  123 300  300 
# 6 3/31/2014  456 400  400 
my_fun(machines %>% group_by(Model.Num), "Cost") 
# Source: local data frame [6 x 4] 
# Groups: Model.Num [2] 
# 
# Date Model.Num Cost position 
# <fctr> <fctr> <dbl> <dbl> 
# 1 1/31/2014  123 200  200 
# 2 1/31/2014  456 300  300 
# 3 2/28/2014  123 250  450 
# 4 2/28/2014  456 350  650 
# 5 3/31/2014  123 300  750 
# 6 3/31/2014  456 400  1050 
Problemi correlati