2015-02-08 16 views
6

Sử dụng dplyr, tôi muốn tóm tắt [sic] theo biến mà tôi có thể thay đổi (ví dụ: trong vòng lặp hoặc lệnh kiểu áp dụng).Gọi theo nhóm có lập trình group_by() trên biến số khác nhau

Gõ tên trực tiếp hoạt động tốt:

library(dplyr) 
ChickWeight %>% group_by(Chick, Diet) %>% summarise(mw = mean(weight)) 

Nhưng group_by đã không được viết để có một vector nhân vật, vì vậy đi qua trong kết quả là khó khăn hơn.

v <- "Diet" 
ChickWeight %>% group_by(c("Chick", v)) %>% summarise(mw = mean(weight)) 
## Error 

Tôi sẽ đăng một giải pháp, nhưng tò mò muốn biết cách người khác giải quyết vấn đề này.

+1

:-) 'tóm tắt [sic]' +1 –

+4

Chỉ cần 'group_by_ (c (" Chick ", v))' thay vì 'group_by (c (" Chick ", v))' .... –

+0

@Ari Nếu bạn sử dụng chính tả của Mỹ, tại sao bạn sử dụng 'tóm tắt' trong mã? –

Trả lời

11

Các chức năng của gạch dplyr có thể hữu ích cho điều đó:

ChickWeight %>% group_by_("Chick", v) %>% summarise(mw = mean(weight)) 

Từ new features in dplyr 0.3:

Bây giờ bạn có thể lập trình với dplyr - mọi hàm sử dụng đánh giá không chuẩn (NSE) cũng có một cặp đánh giá chuẩn (SE) kết thúc bằng _. Ví dụ, phiên bản SE của bộ lọc() được gọi là bộ lọc _(). Phiên bản SE của mỗi hàm có các đối số tương tự nhau, nhưng chúng phải được "trích dẫn" một cách rõ ràng.

0

Đây là một giải pháp và cách tôi đến.

group_by mong đợi điều gì?

> group_by 
function (x, ..., add = FALSE) 
{ 
    new_groups <- named_dots(...) 

Xuống hang thỏ:

> dplyr:::named_dots 
function (...) 
{ 
    auto_name(dots(...)) 
} 
<environment: namespace:dplyr> 
> dplyr:::auto_name 
function (x) 
{ 
    names(x) <- auto_names(x) 
    x 
} 
<environment: namespace:dplyr> 
> dplyr:::auto_names 
function (x) 
{ 
    nms <- names2(x) 
    missing <- nms == "" 
    if (all(!missing)) 
     return(nms) 
    deparse2 <- function(x) paste(deparse(x, 500L), collapse = "") 
    defaults <- vapply(x[missing], deparse2, character(1), USE.NAMES = FALSE) 
    nms[missing] <- defaults 
    nms 
} 
<environment: namespace:dplyr> 
> dplyr:::names2 
function (x) 
{ 
    names(x) %||% rep("", length(x)) 
} 

Sử dụng thông tin đó, làm thế nào để đi về việc tạo ra một giải pháp?

# Naive solution fails: 
ChickWeight %>% do.call(group_by, list(Chick, Diet)) %>% summarise(mw = mean(weight)) 

# Slightly cleverer: 
do.call(group_by, list(x = ChickWeight, Chick, Diet, add = FALSE)) %>% summarise(mw = mean(weight)) 
## But still fails with, 
## Error in do.call(group_by, list(x = ChickWeight, Chick, Diet, add = FALSE)) : object 'Chick' not found 

Giải pháp nằm trong trích dẫn các đối số để đánh giá của họ bị trì hoãn cho đến khi họ đang ở trong môi trường bao gồm các x tbl:

do.call(group_by, list(x = ChickWeight, quote(Chick), quote(Diet), add = FALSE)) %>% summarise(mw = mean(weight)) 
## Bingo! 
v <- "Diet" 
do.call(group_by, list(x = ChickWeight, quote(Chick), substitute(a, list(a = v)), add = FALSE)) %>% summarise(mw = mean(weight)) 
Các vấn đề liên quan