2012-04-19 24 views
12

này được minh họa tốt nhất với một ví dụThống kê tóm tắt theo hai hoặc nhiều biến yếu tố?

str(mtcars) 
mtcars$gear <- factor(mtcars$gear, labels=c("three","four","five")) 
mtcars$cyl <- factor(mtcars$cyl, labels=c("four","six","eight")) 
mtcars$am <- factor(mtcars$am, labels=c("manual","auto") 
str(mtcars) 
tapply(mtcars$mpg, mtcars$gear, sum) 

Điều đó mang lại cho tôi những mpg tóm tắt cho mỗi thiết bị. Nhưng nói rằng tôi muốn có một bảng 3x3 với bánh răng trên đầu trang và cyl xuống bên, và 9 tế bào với số tiền bivariate trong, làm thế nào tôi sẽ nhận được rằng 'thông minh'.

Tôi có thể đi.

tapply(mtcars$mpg[mtcars$cyl=="four"], mtcars$gear[mtcars$cyl=="four"], sum) 
tapply(mtcars$mpg[mtcars$cyl=="six"], mtcars$gear[mtcars$cyl=="six"], sum) 
tapply(mtcars$mpg[mtcars$cyl=="eight"], mtcars$gear[mtcars$cyl=="eight"], sum) 

Điều này có vẻ cồng kềnh.

Sau đó, tôi sẽ mang biến số thứ 3 trong danh sách kết hợp như thế nào?

Điều này phần nào trong không gian tôi đang nghĩ đến. Summary statistics using ddply

cập nhật Điều này giúp tôi ở đó nhưng không đẹp.

aggregate(mpg ~ am+cyl+gear, mtcars,sum) 

Cheers

Trả lời

32

Làm thế nào về điều này, vẫn còn sử dụng tapply()? Nó linh hoạt hơn bạn biết!

with(mtcars, tapply(mpg, list(cyl, gear), sum)) 
#  three four five 
# four 21.5 215.4 56.4 
# six 39.5 79.0 19.7 
# eight 180.6 NA 30.8 

Hoặc, nếu bạn muốn in ra để có thể phiên dịch được nhiều hơn một chút:

with(mtcars, tapply(mpg, list("Cylinder#"=cyl, "Gear#"=gear), sum)) 

Nếu bạn muốn sử dụng nhiều hơn hai biến cross-phân loại, ý tưởng là chính xác giống nhau. Kết quả sau đó sẽ được trả lại trong một mảng 3-hoặc-hơn-chiều:

A <- with(mtcars, tapply(mpg, list(cyl, gear, carb), sum)) 

dim(A) 
# [1] 3 3 6 
lapply(1:6, function(i) A[,,i]) # To convert results to a list of matrices 

# But eventually, the curse of dimensionality will begin to kick in... 
table(is.na(A)) 
# FALSE TRUE 
# 12 42 
+0

Điều này có vẻ là câu trả lời rõ ràng, xem xét rằng tapply với một yếu tố là điểm khởi đầu. 'ftable' cũng có thể được quan tâm. –

3

Tôi thích câu trả lời của Josh cho điều này, nhưng reshape2 cũng có thể cung cấp một khuôn khổ tốt đẹp cho các loại của các vấn đề:

library(reshape2) 

#use subset to only grab the variables of interest... 
mtcars.m <- melt(subset(mtcars, select = c("mpg", "gear", "cyl")), measure.vars="mpg") 
#cast into appropriate format 
dcast(mtcars.m, cyl ~ gear, fun.aggregate=sum, value.var="value") 

    cyl three four five 
1 four 21.5 215.4 56.4 
2 six 39.5 79.0 19.7 
3 eight 180.6 0.0 30.8 
+0

Tôi đã chỉnh sửa để đặt dấu ngoặc kép quanh '' mpg ''được chuyển đến' measure.vars', b/c mã không làm việc cho tôi. Điều đó có phù hợp với bạn không? Ngoài ra, có cách nào dễ dàng để có được điều này để trả về 'NA' thay vì' 0' ở giữa hàng dưới cùng không? –

+0

@ JoshO'Brien - rất lạ, tôi không biết tại sao lại làm việc trước đây mà không có dấu ngoặc kép xung quanh mpg ... cảm ơn vì điều đó. Ngoài ra, tham số 'fill' thành' dcast' sẽ cho phép NA, nhưng tôi nhận được một lỗi lạ ... thiết lập 'fill = Inf' hoặc bất kỳ giá trị số nào khác hoạt động. Đây không phải là những gì tôi mong đợi từ chức năng ... sẽ đào sâu hơn nữa – Chase

5

Tôi nghĩ rằng các câu trả lời đã có trên câu hỏi này là các tùy chọn tuyệt vời, nhưng tôi muốn chia sẻ một tùy chọn bổ sung dựa trên gói dplyr (điều này đã xảy ra với tôi) bởi vì tôi đang dạy một lớp ngay bây giờ khi chúng tôi sử dụng dplyr để thao tác dữ liệu vì vậy tôi muốn tránh giới thiệu sinh viên với các hàm R cơ bản chuyên biệt như tapply hoặc aggregate).

Bạn có thể nhóm vào bao nhiêu biến số tùy ý bằng cách sử dụng chức năng group_by và sau đó tóm tắt thông tin từ các nhóm này với summarize. Tôi nghĩ rằng mã này là dễ đọc hơn để một người mới R so với giao diện dựa trên công thức của aggregate, mang lại kết quả giống hệt nhau:

library(dplyr) 
mtcars %>% 
    group_by(am, cyl, gear) %>% 
    summarize(mpg=sum(mpg)) 
#  am cyl gear mpg 
# (dbl) (dbl) (dbl) (dbl) 
# 1  0  4  3 21.5 
# 2  0  4  4 47.2 
# 3  0  6  3 39.5 
# 4  0  6  4 37.0 
# 5  0  8  3 180.6 
# 6  1  4  4 168.2 
# 7  1  4  5 56.4 
# 8  1  6  4 42.0 
# 9  1  6  5 19.7 
# 10  1  8  5 30.8 

Với hai biến, bạn có thể tóm tắt với một biến trên các hàng và các khác trên cột bằng cách thêm một cuộc gọi đến spread chức năng từ gói tidyr:

library(dplyr) 
library(tidyr) 
mtcars %>% 
    group_by(cyl, gear) %>% 
    summarize(mpg=sum(mpg)) %>% 
    spread(gear, mpg) 
#  cyl  3  4  5 
# (dbl) (dbl) (dbl) (dbl) 
# 1  4 21.5 215.4 56.4 
# 2  6 39.5 79.0 19.7 
# 3  8 180.6 NA 30.8 
0

Câu trả lời có chứa cùng một lượng sử dụng tapply và chức năng tổng hợp.

Tôi muốn thêm một số thông tin vào câu trả lời của Josh O'Brien. Người dùng có thể sử dụng chức năng tổng hợp hoặc tapply tùy thuộc vào đầu ra. Để sử dụng nhiều hơn một biến yếu tố trong tapply một có thể sử dụng phương pháp Josh đã hiển thị.

Đang tải dữ liệu

data("mtcars") 

Sử dụng tapply

with(mtcars, tapply(mpg, list("Cylinder#"=cyl, "Gear#"=gear), sum)) 

Kết quả của đoạn mã trên là

 Gear# 
Cylinder#  3  4 5 
    4  21.5 215.4 56.4 
    6  39.5 79.0 19.7 
    8 180.6 NA 30.8 

Sử dụng chức năng tổng hợp

with(mtcars, aggregate(mpg, list(Cylinder = cyl, Gear = gear), sum)) 

Sản lượng chức năng tổng hợp

Cylinder Gear x 
1  4 3 21.5 
2  6 3 39.5 
3  8 3 180.6 
4  4 4 215.4 
5  6 4 79.0 
6  4 5 56.4 
7  6 5 19.7 
8  8 5 30.8 

Bây giờ nếu người dùng muốn cùng đầu ra như chức năng tổng hợp nhưng sử dụng tapply.

as.data.frame(as.table(with(mtcars, tapply(mpg, list("Cylinder#"=cyl, "Gear#"=gear), 
sum)))) 

Sản lượng chức năng tapply

Cylinder. Gear. Freq 
1   4  3 21.5 
2   6  3 39.5 
3   8  3 180.6 
4   4  4 215.4 
5   6  4 79.0 
6   8  4 NA 
7   4  5 56.4 
8   6  5 19.7 
9   8  5 30.8 

NA có thể được nhận giữ hộ, loại bỏ theo yêu cầu kinh doanh.