2015-01-17 19 views
6

Có cách nào để chuyển chuỗi dưới dạng tham chiếu cột đến quy trình dplyr không?chuỗi dplyr dưới dạng tham chiếu cột

Dưới đây là ví dụ - với tập dữ liệu được nhóm và một hàm đơn giản mà tôi cố gắng chuyển một chuỗi làm tham chiếu đến một cột. Cảm ơn!

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

Bạn nên đọc nign họa tiết ('vignette (" nse ", package =" dplyr ")', nó giải quyết chính xác tình huống này. – Ista

Trả lời

7

Dưới đây là một lựa chọn có sử dụng interp() từ gói lazyeval, mà đi kèm với bạn dplyr cài đặt. Bên trong (các) hàm của bạn, bạn sẽ cần sử dụng phiên bản đánh giá chuẩn của các hàm dplyr. Trong trường hợp này sẽ là mutate_().

Lưu ý rằng cột mới position sẽ giống hệt với cột Cost ở đây vì cách bạn đã thiết lập nhóm trong machines. Cuộc gọi thứ hai tới số my_fun() cho biết nó hoạt động trên một nhóm các biến nhóm khác nhau.

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

Chúng tôi có thể đánh giá trong đánh giá tiêu chuẩn mà không cần sử dụng gói lazyeval. Chúng tôi có thể thiết lập một số chuỗi như tên biến bằng cách sử dụng 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 
Các vấn đề liên quan