2012-03-08 21 views
17

Đây là một câu hỏi đơn giản nhưng tôi không thể tìm ra cách sử dụng prop.table cho điều này và tôi cần chức năng này rất thường xuyên.Trong R, làm thế nào tôi có thể tính toán số liệu thống kê phần trăm trên một cột trong một khung dữ liệu? (bảng chức năng mở rộng với tỷ lệ phần trăm)

Tôi có dữ liệu như thế này

> library(ggplot2) 
> #sample data 
> head(tips,3) 
    total_bill tip sex smoker day time size 
1   17 1.0 Female  No Sun Dinner 2 
2   10 1.7 Male  No Sun Dinner 3 
3   21 3.5 Male  No Sun Dinner 3 
> #how often there is a non-smoker 
> table(tips$smoker) 

No Yes 
151 93 
> #how many subjects 
> nrow(tips) 
[1] 244 

Và tôi cần phải biết tỷ lệ người hút thuốc so với không hút thuốc Something như thế này (mã xấu xí):

> #percentage of smokers 
> options(digits=2) 
> transform(as.data.frame(table(tips$smoker)),percentage_column=Freq/nrow(tips)*100) 
    Var1 Freq percentage_column 
1 No 151    62 
2 Yes 93    38 
> 

Có cách nào tốt hơn để làm cái này?

(thậm chí tốt hơn nó sẽ là để làm điều này trên một tập hợp các cột (mà tôi liệt kê) và có đầu ra hơi độc đáo được định dạng) (ví dụ, người hút thuốc, ngày và thời gian)

+0

lời khuyên là một tập dữ liệu trong gói ggplot2 – userJT

Trả lời

42

Nếu đó là conciseness bạn sau đó, bạn có thể thích:

prop.table(table(tips$smoker)) 

và sau đó quy mô 100 và tròn nếu bạn muốn. Hoặc nhiều hơn như sản lượng chính xác của bạn:

tbl <- table(tips$smoker) 
cbind(tbl,prop.table(tbl)) 

Nếu bạn muốn làm điều này cho nhiều cột, có rất nhiều hướng khác nhau mà bạn có thể đi tùy thuộc vào những gì thị hiếu của bạn nói với bạn là sạch đầu ra nhìn, nhưng đây là một lựa chọn:

tblFun <- function(x){ 
    tbl <- table(x) 
    res <- cbind(tbl,round(prop.table(tbl)*100,2)) 
    colnames(res) <- c('Count','Percentage') 
    res 
} 

do.call(rbind,lapply(tips[3:6],tblFun)) 
     Count Percentage 
Female 87  35.66 
Male  157  64.34 
No  151  61.89 
Yes  93  38.11 
Fri  19  7.79 
Sat  87  35.66 
Sun  76  31.15 
Thur  62  25.41 
Dinner 176  72.13 
Lunch  68  27.87 

Nếu bạn không thích xếp chồng lên nhau các bảng khác nhau, bạn có thể bỏ số do.call và để chúng trong danh sách.

+0

hmm .. Tôi đã không nghĩ về "chaining" bàn và prop.table như cái đó. làm cách nào để thực hiện điều đó cho nhiều cột được liệt kê ...? – userJT

+0

@ user56 Đã chỉnh sửa với một ví dụ có thể (nhưng có rất nhiều cách khác nhau để tiếp cận những gì bạn mô tả). – joran

+0

có thể dplyr thêm chức năng như vậy (tất cả chúng ta sử dụng tất cả thời gian) – userJT

9

Mã của bạn không có vẻ xấu xí với tôi ...
tuy nhiên, một thay thế (không tốt hơn nhiều) có thể là ví dụ :

df <- data.frame(table(yn)) 
colnames(df) <- c('Smoker','Freq') 
df$Perc <- df$Freq/sum(df$Freq) * 100 

------------------ 
    Smoker Freq Perc 
1  No 19 47.5 
2 Yes 21 52.5 
4

Tôi không chắc chắn 100%, nhưng tôi nghĩ điều này thực hiện những gì bạn muốn bằng cách sử dụng prop.table. Xem phần lớn 3 dòng cuối cùng. Phần còn lại của mã chỉ là tạo dữ liệu giả.

set.seed(1234) 

total_bill <- rnorm(50, 25, 3) 
tip <- 0.15 * total_bill + rnorm(50, 0, 1) 
sex <- rbinom(50, 1, 0.5) 
smoker <- rbinom(50, 1, 0.3) 
day <- ceiling(runif(50, 0,7)) 
time <- ceiling(runif(50, 0,3)) 
size <- 1 + rpois(50, 2) 
my.data <- as.data.frame(cbind(total_bill, tip, sex, smoker, day, time, size)) 
my.data 

my.table <- table(my.data$smoker) 

my.prop <- prop.table(my.table) 

cbind(my.table, my.prop) 
0

Tôi làm điều này cho khi thực hiện chức năng tổng hợp và tương tự

per.fun <- function(x) { 
    if(length(x)>1){ 
     denom <- length(x); 
     num <- sum(x); 
     percentage <- num/denom; 
     percentage*100 
     } 
     else NA 
    } 
Các vấn đề liên quan